 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
The following code is perfectly valid to the present version, but does not
produce anything.
#declare FooCount = 0 ;
#while (FooCount < 100 )
sphere {<0,FooCount,0>,1 pigment { rgb< 1, 1, 0> } }
// #declare FooCount = FooCount + 1 ; // note this missing line
#end
I suppose that a "detector" of infinite loops is it too much to ask?
B. Gimeno
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"bgimeno" <bgimeno[at]persistencia[dot]org> wrote:
> #declare FooCount = 0 ;
> #while (FooCount < 100 )
> sphere {<0,FooCount,0>,1 pigment { rgb< 1, 1, 0> } }
> // #declare FooCount = FooCount + 1 ; // note this missing line
> #end
You're not the first one to do this :)
> I suppose that a "detector" of infinite loops is it too much to ask?
What should be the detection criterion?
I want a proper for-loop anyway.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
bgimeno <bgimeno[at]persistencia[dot]org> wrote:
> I suppose that a "detector" of infinite loops is it too much to ask?
It is, in fact. How do you detect an infinite loop? That's especially
difficult given that it has been mathematically proven to be an impossible
task in the general case.
You could put an enforced upper limit to any loop, but how large would
that upper limit be? What if you really need to go over that limit? Also
an upper limit is not of much help if the body of the loop takes a very
long time to parse anyways: The upper limit would not be triggered anytime
soon.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"bgimeno" <bgimeno[at]persistencia[dot]org> wrote:
> The following code is perfectly valid to the present version, but does not
> produce anything.
>
> #declare FooCount = 0 ;
> #while (FooCount < 100 )
> sphere {<0,FooCount,0>,1 pigment { rgb< 1, 1, 0> } }
> // #declare FooCount = FooCount + 1 ; // note this missing line
> #end
>
> I suppose that a "detector" of infinite loops is it too much to ask?
>
> B. Gimeno
When I write a counting loop, I tend to do it as follows:
#declare FooCount = 0 ; #while (FooCount < 100 )
> BLAH BLAH BLAH
#declare FooCount = FooCount + 1 ; #end
I know there are circumstances where this can't be done, but I find it helps me
recognize my "for" type loops easily.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
I don't know if there is a special case in which a loop of the variable
"FooCounter" should remain unchanged.
But what about a simple detector where the value of "FooCounter" from the
#while(FooCounter cond) condition does not change when you reach the end of
the loop?.
If this is an "insurmountable" logical hole guess we will have to settle for
what is, but thanks anyway for your reply.
B. Gimeno
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
bgimeno <bgimeno[at]persistencia[dot]org> wrote:
> I don't know if there is a special case in which a loop of the variable
> "FooCounter" should remain unchanged.
> But what about a simple detector where the value of "FooCounter" from the
> #while(FooCounter cond) condition does not change when you reach the end of
> the loop?.
Just because it didn't change in one loop doesn't mean it will never
change.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"bgimeno" <bgimeno[at]persistencia[dot]org> wrote:
> I don't know if there is a special case in which a loop of the variable
> "FooCounter" should remain unchanged.
> But what about a simple detector where the value of "FooCounter" from the
> #while(FooCounter cond) condition does not change when you reach the end of
> the loop?.
>
> If this is an "insurmountable" logical hole guess we will have to settle for
> what is, but thanks anyway for your reply.
>
> B. Gimeno
Actually, I just wrote some code that has that. The loop counter is
conditionally incremented, and the condition isn't known until after it is
evaluated. I cut out some earlier code that wasn't relevant (mostly file
writing stuff).
#local i = 0;
#local seaweedCount = 10000;
#while( i < seaweedCount )
#local xcord = xdist * rand(rs1) + bounds1.x;
#local zcord = zdist * rand(rs1) + bounds1.z;
#local normVect = <0,0,0>;
#local intersectVect = trace(o_rocks,<xcord,10,zcord>, <0.5,-1,1>,
normVect);
#if( intersectVect.y < waterLevel + 0.5 )
sphere
{
intersectVect, 0.05
texture{ marker1s }
}
#local i = i + 1;
#end
#end
Basically it selects a random point within the bounds of a heightfield, then
uses trace to find the exact point on the heightfield. It then checks to make
sure the point is close to the water level. If the point isn't slightly above
the water level or lower, the counter is not incremented. In this way I get
seaweedCount (10000) objects where I need them, and not 10000 total attempts to
place an object, whether it is successful or not.
It is quite possible to place a secondary condition so that it "bails out" after
some very high number of tries, but only the individual user can decide for a
given instance of where and what that condition should be.
-Reactor
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
It's not really an infinite loop condition detector but a "I forgot to increment
my variable"-detector:
Check if the loop condition variable is being reassigned inside the loop.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Aydan <hes### [at] hendrik-sachse net> wrote:
> Check if the loop condition variable is being reassigned inside the loop.
Impossible in the general case.
Besides, you are assuming that there is a single unambiguous "loop condition
variable". The condition in the #while construct can be *anything*. It can be
a complex expression, it can be a function or macro call, it can contain a
condition composed of many variables...
For example, if you had something like this:
#while(xCoord * 2.5 < yCoord * 5 & sqrt(zCoord) < 10 * zSize)
how would POV-Ray check that this isn't an infinite loop?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Check if the loop condition variable is being reassigned inside the loop.
>
> Impossible in the general case.
>
> Besides, you are assuming that there is a single unambiguous "loop
> condition
> variable". The condition in the #while construct can be *anything*. It can
> be
> a complex expression, it can be a function or macro call, it can contain a
> condition composed of many variables...
>
> For example, if you had something like this:
>
> #while(xCoord * 2.5 < yCoord * 5 & sqrt(zCoord) < 10 * zSize)
>
> how would POV-Ray check that this isn't an infinite loop?
Impossible to catch all infinite loops, but the parser could check to make
sure at least one of the variables mentioned in the #while condition is
reassigned within the loop. That would catch a lot of mistakes (eg
forgetting to increment the index variable).
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"bgimeno" <bgimeno[at]persistencia[dot]org> wrote:
> I don't know if there is a special case in which a loop of the variable
> "FooCounter" should remain unchanged.
> But what about a simple detector where the value of "FooCounter" from the
> #while(FooCounter cond) condition does not change when you reach the end of
> the loop?.
First of all, this would require special handling for conditional expressions to
detect the presence of such a construct during parsing.
Furthermore, consider this:
#declare R = seed(4711);
#declare Items = 0;
#while (Items < 10000)
#declare MyPos = SomeRandomPosition(R);
#if (SomeCondition(MyPos))
DoSomething(MyPos)
#declare Items = Items + 1;
#end
#end
Obviously, the problem is more complicated than just checking whether the
variable value actually changes in each loop: Runtime checking won't do, you'd
need code analysis. Also note that the increment may be hidden nested deeply in
macros, so this is not a straightforward check for the existence of a "#declare
FooCounter = ..." somewhere inside the loop.
In my eyes it would be a kludge anyway, so why not heal the leg instead, and add
a proper #for loop - I'm sure we'd have that issue solved then.
(If POV 4 does indeed get a new SDL as promised, I'm quite sure it will not come
without a for loop anyway.)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> Impossible to catch all infinite loops, but the parser could check to make
> sure at least one of the variables mentioned in the #while condition is
> reassigned within the loop. That would catch a lot of mistakes (eg
> forgetting to increment the index variable).
What if it's not incremented within the loop? Maybe it's incremented
elsewhere (eg. inside a macro called from the loop).
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"scott" <sco### [at] scott com> wrote:
> Impossible to catch all infinite loops, but the parser could check to make
> sure at least one of the variables mentioned in the #while condition is
> reassigned within the loop. That would catch a lot of mistakes (eg
> forgetting to increment the index variable).
What if we're talking about a loop like this:
#declare abortProb = 0.03;
#while(rand(R) > abortProb)
//...
#end
Still insist on the variable being re-assigned? What if not rand() is used, but
some macro creating a non-uniform distribution?
What if no variable is used at all, as in:
#while(rand(R) > 0.03)
//...
#end
I do know I keep repeating myself, but: Why on earth try to come up with
ever-so-complex ways to detect a broken counting #while loop without breaking
other uses of the #while statement, when really the root problem is the absence
of a proper #for loop?
Virtually no-one is asking for an infinite loop detection in other languages
like Pascal, C, VB or what-have-you. Why? Because they do have a for-loop so
you usually don't encounter this blunder there.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> What if it's not incremented within the loop? Maybe it's incremented
> elsewhere (eg. inside a macro called from the loop).
Does the parser re-parse a macro each time it is called?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> What if we're talking about a loop like this:
>
> #declare abortProb = 0.03;
> #while(rand(R) > abortProb)
> //...
> #end
Well rand() gives a different answer each time, so that can automatically be
counted as being reassigned in the eyes of the infinite-loop-catcher. If
you try to implement your own RNG in a macro then obviously the random
variable will be reassigned so that would also count.
> I do know I keep repeating myself, but: Why on earth try to come up with
> ever-so-complex ways to detect a broken counting #while loop without
> breaking
> other uses of the #while statement, when really the root problem is the
> absence
> of a proper #for loop?
Agreed. Although I still think you could detect some common infinite loop
situations without breaking any existing behaviour.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> "scott" <sco### [at] scott com> wrote:
> I do know I keep repeating myself, but: Why on earth try to come up with
> ever-so-complex ways to detect a broken counting #while loop without breaking
> other uses of the #while statement, when really the root problem is the absence
> of a proper #for loop?
>
> Virtually no-one is asking for an infinite loop detection in other languages
> like Pascal, C, VB or what-have-you. Why? Because they do have a for-loop so
> you usually don't encounter this blunder there.
I really dont see the need for a FOR loop. In the most general sense, FOR loops
just increment from one value to another at a preset interval. FOR loops are
essentially just specialized WHILE loops and very easy to implement in POV
without causing errors.
FOR i = 1 to 6 STEP j
...
NEXT j
#declare i=1; #while (i<=6)
...
#declare i=i+j; #end
Most of the infinite loop situations that have been presented would not be
solved properly with a FOR loop. For example, any of the conditional increment
type loops (counter is increased only if a certain condition is met) require
extra steps in a FOR loop to work:
#declare i=1; #while (i<6)
...
#if(condition)
#declare i=i+j;
#end
#end
FOR i = 1 to 6 STEP j
...
IF (NOT condition)
i=i-j
ENDIF
NEXT j
I don't think that there are any 'infinite loop' detectors that would be of
universal value to add to POV. I little bit of diligence and debugging on the
part of the user can easily overcome any issue. In the past, whenever I have
put together a #while loop that isn't working properly, setting up value
reporting with the #debug statement usually was able to show if a value wasn't
progressing as expected and help pinpoint the problem.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > What if it's not incremented within the loop? Maybe it's incremented
> > elsewhere (eg. inside a macro called from the loop).
> Does the parser re-parse a macro each time it is called?
Currently yes.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > What if we're talking about a loop like this:
> >
> > #declare abortProb = 0.03;
> > #while(rand(R) > abortProb)
> > //...
> > #end
> Well rand() gives a different answer each time, so that can automatically be
> counted as being reassigned in the eyes of the infinite-loop-catcher. If
> you try to implement your own RNG in a macro then obviously the random
> variable will be reassigned so that would also count.
Which one of the myriad of variables inside a potential macro call should
be enough change to decide that it's not an infinite loop?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"scott" <sco### [at] scott com> wrote:
> > What if it's not incremented within the loop? Maybe it's incremented
> > elsewhere (eg. inside a macro called from the loop).
>
> Does the parser re-parse a macro each time it is called?
Yes - at least the POV 3.x parser does. Chances are a POV 4 parser will not.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"scott" <sco### [at] scott com> wrote:
> Agreed. Although I still think you could detect some common infinite loop
> situations without breaking any existing behaviour.
The problem here, and the point some of us are trying to make, is that those
"common infinite loop situations" would be riddled with "uncommon finite loop
situation" exceptions, which all would have to be tested for in order to not
break anything.
As for an exhaustive test, it is absolutely *impossible* to do:
POV-Ray's SDL is "Turing-complete", a term from theoretical informatics roughly
eqivalent to saying, "you can use it to write *any* program you can ever
imagine" (leaving aside memory and performance constraints, that is).
Now there is a problem in theoretical informatics known as the "halting
problem": Given an arbitrary program and an arbitrary input, decide whether the
program will ultimately finish, or instead run forever. In 1936, Alan Turing
proved that for the general case of a Turing-complete engine, this halting
problem is *not* decidable - in other words, for each and every Turing-complete
programming language it is *impossible* to come up with a generic algorithm that
can predict from any given program and any given starting conditions whether it
will enter an infinite loop or not.
It is possible to restrict a computer language in such a way as to force the
halting problem to be decideable for that engine, but only at the cost of no
longer being Turing-complete, i.e. reduction of *some* functionality.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> I really dont see the need for a FOR loop. In the most general sense, FOR loops
> just increment from one value to another at a preset interval. FOR loops are
> essentially just specialized WHILE loops and very easy to implement in POV
> without causing errors.
From a theoretical point of view you're perfectly right, but from a practical
point of view you're absolutely wrong.
The most common case of loop construct used in POV-Ray SDL is the standard
countng loop:
#declare i = 1;
#while (i <= 10000)
//...
#declare i = i + 1;
#end
There is a lot of unnecessary typing involved here, and some of it is too easily
forgotten; as an aside, the loop construct, although perfectly documenting the
technical workings of the loop, doesn't make the programmer's original
intentions all too obvious, because it "atomizes" the whole loop into many
separate statements. The "#declare i = 1;" can easily get lost among other loop
initialization statements, and the "#declare i = i + 1;" can easily get lost
among the loop body. It's also quite inconsistent: Why would the start of the
range over which to loop be mentioned in a "#declare" statement, while only the
end of the range would be mentioned in the loop statement itself?
On the other hand, something like
#for (i = 1 to 10000)
//...
#end
is much more concise, avoids unnecessary typing (no typing the loop variable 4
times and typing #declare twice, as in the #while version), shows better what's
going on here, is consistent in mentioning both start and end of the number
range in the loop statement itself, and - best of all - avoids the
all-too-common mistake of forgettig to increment.
If you think the #while loop is good enough, feel free to continue to use it,
but please - just because *you* don't need it, don't hinder others from getting
it. The current #while loop *is* a PITA for quite some folks, me included.
> FOR i = 1 to 6 STEP j
> ...
> NEXT j
>
> #declare i=1; #while (i<=6)
> ...
> #declare i=i+j; #end
Interestingly, you made all attempts to "compactify" the #while code, but not so
with the FOR code. How come?
Now give that loop variable a more verbose name, say CurrentIdx:
#for (CurrentIdx = 1 to 6 step j)
// ...
#end
or
#declare CurrentIdx = 1; #while (CurrentIdx <= 6)
// ...
#declare CurrentIdx = CurrentIdx + 1; #end
I know which version I'd prefer.
Also note that your version of trying to integrate the initialization and
increment into the loop itself leaves you with the "#while" and "#end" right in
the middle and the end of a line, respectively, making it difficult to visually
identify and match these statements quickly in the code.
> Most of the infinite loop situations that have been presented would not be
> solved properly with a FOR loop. For example, any of the conditional increment
> type loops (counter is increased only if a certain condition is met) require
> extra steps in a FOR loop to work:
There's a difference here between statements that commonly create infinite
loops, and statements that an infinite-loop detector would have to be able to
properly cope with.
The loop that counts each and every iteration is *the* standard case, and also
*the* standard reason for undesired infinite loops. That's *the* classic use
case for a for-loop. If you want to count up only in certain cases, you're much
less likely to forget it - and it's also comparatively uncommon; for these
cases, #while-loops would continue to be the weapon of choice.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Now there is a problem in theoretical informatics known as the "halting
> problem": Given an arbitrary program and an arbitrary input, decide
> whether the
> program will ultimately finish, or instead run forever. In 1936, Alan
> Turing
> proved that for the general case of a Turing-complete engine, this halting
> problem is *not* decidable - in other words, for each and every
> Turing-complete
> programming language it is *impossible* to come up with a generic
> algorithm that
> can predict from any given program and any given starting conditions
> whether it
> will enter an infinite loop or not.
I'm not saying it's possible to detect whether any program will stop or not.
I'm saying that in *some* cases you can relatively easily detect that it
won't stop without changing the functionality.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Well rand() gives a different answer each time, so that can automatically
>> be
>> counted as being reassigned in the eyes of the infinite-loop-catcher. If
>> you try to implement your own RNG in a macro then obviously the random
>> variable will be reassigned so that would also count.
>
> Which one of the myriad of variables inside a potential macro call should
> be enough change to decide that it's not an infinite loop?
"at least one of the variables mentioned in the #while condition"
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> >> Well rand() gives a different answer each time, so that can automatically
> >> be
> >> counted as being reassigned in the eyes of the infinite-loop-catcher. If
> >> you try to implement your own RNG in a macro then obviously the random
> >> variable will be reassigned so that would also count.
> >
> > Which one of the myriad of variables inside a potential macro call should
> > be enough change to decide that it's not an infinite loop?
> "at least one of the variables mentioned in the #while condition"
What if there are no variables mentioned there?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> What if there are no variables mentioned there?
It can just ignore it, the purpose is to catch a mistake like when you
forget to increment the index counter, not catch all infinite loops (that is
impossible).
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > What if there are no variables mentioned there?
> It can just ignore it, the purpose is to catch a mistake like when you
> forget to increment the index counter, not catch all infinite loops (that is
> impossible).
If the variable mentioned in the condition is not the variable which
changes and decides when the loop ends, the checker would give a false
positive.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> If the variable mentioned in the condition is not the variable which
> changes and decides when the loop ends, the checker would give a false
> positive.
Can you give an example - I don't understand how that would work (I thought
that the condition decided when the loop ended).
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > If the variable mentioned in the condition is not the variable which
> > changes and decides when the loop ends, the checker would give a false
> > positive.
> Can you give an example - I don't understand how that would work (I thought
> that the condition decided when the loop ended).
#declare Limit = .8;
#while(MyRand() < Limit)
doSomething();
#end
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> scott <sco### [at] scott com> wrote:
> > > What if there are no variables mentioned there?
>
> > It can just ignore it, the purpose is to catch a mistake like when you
> > forget to increment the index counter, not catch all infinite loops (that is
> > impossible).
>
> If the variable mentioned in the condition is not the variable which
> changes and decides when the loop ends, the checker would give a false
> positive.
>
> --
> - Warp
Perhaps the easiest and most universal solution to implement would be to add a
global "loop_limit" variable that would set the maximum number of loops allowed
(similar to max_trace value). POV would then only need to keep track of the
number of iterations the current loop has gone through and kick it out when it
reaches the limit, rather than tracking any number of variables. I would
expect that POV would also report an error (without aborting) to the message
window that a loop was terminated with the line number for debugging purposes.
To allow infinite loops as the current functionality is, one would set
loop_limit to 0 or -1.
The one disadvantage to this is that it would be globaL and apply to all loops
within the scene.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> "Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> > I really dont see the need for a FOR loop. In the most general sense, FOR loops
> > just increment from one value to another at a preset interval. FOR loops are
> > essentially just specialized WHILE loops and very easy to implement in POV
> > without causing errors.
>
> From a theoretical point of view you're perfectly right, but from a practical
> point of view you're absolutely wrong.
>
> The most common case of loop construct used in POV-Ray SDL is the standard
> countng loop:
>
> #declare i = 1;
> #while (i <= 10000)
> //...
> #declare i = i + 1;
> #end
>
> There is a lot of unnecessary typing involved here, and some of it is too easily
> forgotten; as an aside, the loop construct, although perfectly documenting the
> technical workings of the loop, doesn't make the programmer's original
> intentions all too obvious, because it "atomizes" the whole loop into many
> separate statements. The "#declare i = 1;" can easily get lost among other loop
> initialization statements, and the "#declare i = i + 1;" can easily get lost
> among the loop body. It's also quite inconsistent: Why would the start of the
> range over which to loop be mentioned in a "#declare" statement, while only the
> end of the range would be mentioned in the loop statement itself?
>
> On the other hand, something like
>
> #for (i = 1 to 10000)
> //...
> #end
>
> is much more concise, avoids unnecessary typing (no typing the loop variable 4
> times and typing #declare twice, as in the #while version), shows better what's
> going on here, is consistent in mentioning both start and end of the number
> range in the loop statement itself, and - best of all - avoids the
> all-too-common mistake of forgettig to increment.
>
> If you think the #while loop is good enough, feel free to continue to use it,
> but please - just because *you* don't need it, don't hinder others from getting
> it. The current #while loop *is* a PITA for quite some folks, me included.
>
I do agree that a for loop would be more concise and I'm not trying to hinder
you from getting it. It was more a matter of showing that adding a #for
wouldn't add functionality that the current #while loop can't already do, it
just makes things more concise and recognizable, and perhaps easier to use (in
my earlier days I often wished I did have a for loop, however now, I just got
used to using the while loop). If whatever programming overhead involved in
adding #for loop functionality is worth the value of having it, then, by all
means, it could/should be added. The value being in simpler coding rather than
added functionality.
>
> > FOR i = 1 to 6 STEP j
> > ...
> > NEXT j
> >
> > #declare i=1; #while (i<=6)
> > ...
> > #declare i=i+j; #end
>
> Interestingly, you made all attempts to "compactify" the #while code, but not so
> with the FOR code. How come?
>
> Now give that loop variable a more verbose name, say CurrentIdx:
>
> #for (CurrentIdx = 1 to 6 step j)
> // ...
> #end
>
> or
>
> #declare CurrentIdx = 1; #while (CurrentIdx <= 6)
> // ...
> #declare CurrentIdx = CurrentIdx + 1; #end
>
> I know which version I'd prefer.
>
> Also note that your version of trying to integrate the initialization and
> increment into the loop itself leaves you with the "#while" and "#end" right in
> the middle and the end of a line, respectively, making it difficult to visually
> identify and match these statements quickly in the code.
>
Compactifying it wasn't intended to sell one over the other. It was merely to
demonstrate how the #while works as a #for. Combining the lines as shown is
how I write my for-type loops currently to make them recognizable as for loops
and also to not lose the initial value and step function in the code.
> > Most of the infinite loop situations that have been presented would not be
> > solved properly with a FOR loop. For example, any of the conditional increment
> > type loops (counter is increased only if a certain condition is met) require
> > extra steps in a FOR loop to work:
>
> There's a difference here between statements that commonly create infinite
> loops, and statements that an infinite-loop detector would have to be able to
> properly cope with.
>
> The loop that counts each and every iteration is *the* standard case, and also
> *the* standard reason for undesired infinite loops. That's *the* classic use
> case for a for-loop. If you want to count up only in certain cases, you're much
> less likely to forget it - and it's also comparatively uncommon; for these
> cases, #while-loops would continue to be the weapon of choice.
Agreed somewhat. Because of the way I present my for loops, I usually don't
encounter an infinite loop problem. This is where careful coding helps. In
this case it is a visible coding error that can easily be corrected when
identified.
The area I usually encounter inifinite loops is with conditional while loops.
In this case, the error is not noticeable and often not avoidable through
careful programming. A lot of debuggin and variable tracking/watching is often
needed to figure out why the conditional statement isn't triggering.
An example is placing non-intersecting spheres in a box. If the maximum count
is greater than what can actually fit in the volume (i.e., the loop reaches a
point where it can no longer find a big enough space to place a new sphere, but
keeps trying because the max number of objects hasn't been reached), an inifnite
loop will be encountered. This only a simple demonstration as, in reality, it
should be obvious what is causing the inifinite loop once it is located,
however, the presence of the inifinite loop would not (likely) be obvious by
simple examination of the written code (i.e. it is not a coding error).
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Trevor G Quayle <Tin### [at] hotmail com> wrote:
> Perhaps the easiest and most universal solution to implement would be to add a
> global "loop_limit" variable that would set the maximum number of loops allowed
> (similar to max_trace value).
Or to add a #for loop construct.
(I have thrown some suggestions to the team about this.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Can you give an example - I don't understand how that would work (I
>> thought
>> that the condition decided when the loop ended).
>
> #declare Limit = .8;
> #while(MyRand() < Limit)
> doSomething();
> #end
As I already wrote to clipka when he mentioned the rand() function, as the
result could be different each time from a macro, the infinite-loop-checker
effectively would assume that the result was being reassigned each loop, so
not flag it up as an infinite loop.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > #declare Limit = .8;
> > #while(MyRand() < Limit)
> > doSomething();
> > #end
> As I already wrote to clipka when he mentioned the rand() function, as the
> result could be different each time from a macro, the infinite-loop-checker
> effectively would assume that the result was being reassigned each loop, so
> not flag it up as an infinite loop.
How can the checker know that the result is different each time the macro
is called?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> Trevor G Quayle <Tin### [at] hotmail com> wrote:
> > Perhaps the easiest and most universal solution to implement would be to add a
> > global "loop_limit" variable that would set the maximum number of loops allowed
> > (similar to max_trace value).
>
> Or to add a #for loop construct.
>
> (I have thrown some suggestions to the team about this.)
>
> --
> - Warp
Adding the #for loop only solves the problem with a misplaced or missing
increment statement, which is purely a programmer's error that can be largely
avoided with a little diligence by the programmer. Of course this is the type
of infinite loop scenerio that the OP is referring to.
This will not solve other infinite loop problems that are not related to
programmer error such as conditional statements that are never satisfied due to
some issue that is not superficially apparent.
The #for loop would add some ease and conciseness to the coding end and help
users avoid this programming error, but it would not add any functionality
overall that isn't already achievable through a properly constructed #while
loop.
I am not arguing that there is no need for a #for loop. As long as it can be
easily instituted and not become more fluff in the machine, I am all *for* it,
and would likely even use it.
Beyond that, I do think now that a loop_limiter variable as I have described may
have some usage in the SDL. It can help abort and identify existing *infinite*
(or rather, high-count, potentially infinite) loops within the code that are
not apparent to the user in many situations. It may also be of direct intended
usage where the user wants to force loops to terminate after a maximum number of
iterations for whatever reason (this can be done through coding, but it would be
an added benefit of having the global variable).
One further item on the potential creation of #for loops: Would they be best
end-bracketted with the general #end statement (as #while, #if, #switch and
#macro all use)? Or would it be more appropriate to add a "#next" statement or
even "#next n" statement instead? #end would make it more consistent with
current programming practice, but #next would make the #for loop construct more
visible and identifiable. Along this line of thinking, perhaps more specific
#end statements would also be more appropriate for the other situations as
well: #while/#wend, #if/#endif, #switch/(#send?), #macro/(#mend?). Of course
you would likely keep the #end functionality for backwards compatibility.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"scott" <sco### [at] scott com> wrote:
> I'm not saying it's possible to detect whether any program will stop or not.
> I'm saying that in *some* cases you can relatively easily detect that it
> won't stop without changing the functionality.
I'm definitely repeating myself here: Those easy cases would come packaged with
too many not-so-easy special cases.
Sure you can detect a simple
#while (i < N)
//#declare i=...
#end
as being an infinite loop, but that's an absolutely trivial case; as soon as you
go from there to
#while (i < N)
...
//#declare i=...
...
#end
then if you don't find a "#declare i=...", you *must* examine the "..."
thoroughly before you can conclude that the user really forgot it.
Of course, if you *do* find a "#declare i=..." in there, you can tell for sure
the user did *not* forget it; but that doesn't get us any further.
The bottom line is that a potentially-infite-loop detector would be a quite
complex piece of code, even if it were just to catch some standard cases. There
would be much easier and more useful remedies for the forgotten-increment
ailment.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Trevor G Quayle <Tin### [at] hotmail com> wrote:
> One further item on the potential creation of #for loops: Would they be best
> end-bracketted with the general #end statement (as #while, #if, #switch and
> #macro all use)? Or would it be more appropriate to add a "#next" statement or
> even "#next n" statement instead? #end would make it more consistent with
> current programming practice, but #next would make the #for loop construct more
> visible and identifiable.
I don't support the idea of adding new keywords just to serve as comments.
If you want to comment your code, use comments. I personally use this style
quite a lot:
#while(a < b)
some stuff here
#while(c < d)
some other stuff here
#if(something)
more stuff here
#end // #if(something)
additional stuff
#end // #while(c < d)
#end // #while(a < b)
(In fact, I use this style with large blocks when programming in C++ as
well.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp <war### [at] tag povray org> wrote:
> Trevor G Quayle <Tin### [at] hotmail com> wrote:
> > One further item on the potential creation of #for loops: Would they be best
> > end-bracketted with the general #end statement (as #while, #if, #switch and
> > #macro all use)? Or would it be more appropriate to add a "#next" statement or
> > even "#next n" statement instead? #end would make it more consistent with
> > current programming practice, but #next would make the #for loop construct more
> > visible and identifiable.
>
> I don't support the idea of adding new keywords just to serve as comments.
> If you want to comment your code, use comments. I personally use this style
> quite a lot:
>
> #while(a < b)
> some stuff here
>
> #while(c < d)
> some other stuff here
>
> #if(something)
> more stuff here
> #end // #if(something)
>
> additional stuff
>
> #end // #while(c < d)
> #end // #while(a < b)
>
> (In fact, I use this style with large blocks when programming in C++ as
> well.)
>
> --
> - Warp
I wasn't necessarily arguing for the addition of the keywords, just commenting
on whether a #for loop should be consistent with the other constructs and end
with #end. If it was felt that they should have their own #next keyword, then
the extension of that argument would be that all the other constructs should as
well.
I will admit that having a bunch of nested #end statements can become confusing
figuring out which belongs to any of the constructs present without good
commenting and/or scoping. However, adding the commenting does require extra
typing and lessens the conciseness of the construct which is one of the
arguments in favour of adding #for.
One thing you can't do at present would be something along the lines of:
#declare i=0;
#while (i<5)
...
#if (something happens that makes me want to terminate the loop early)
#declare i=-1;
#end
#else
#declare i=i+1;
#end
#end
as the #end statements get confused. Granted this is not good programming
protocol and is achievable by other methods, it is merely a demonstration of a
conceivable issue. Construct-specific end statements could allow for this
(however, leaving #end for backwards compatibility would preclude allowing this
anyways).
All in all, I would support the continued usage of #end for all constructs as
well as for a new #for construct.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Trevor G Quayle <Tin### [at] hotmail com> wrote:
> #declare i=0;
> #while (i<5)
> ...
> #if (something happens that makes me want to terminate the loop early)
> #declare i=-1;
> #end
> #else
> #declare i=i+1;
> #end
> #end
I think that what you wanted to express there is a #break, not an #end.
(No, #break does not currently interrupt loops, although I don't see any
reason why it couldn't.)
You can currently achieve the same effect with:
#declare i=0;
#while (i<5)
...
#if (something happens that makes me want to terminate the loop early)
#declare i=5;
#else
#declare i=i+1;
#end
#end
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> Perhaps the easiest and most universal solution to implement would be to add a
> global "loop_limit" variable that would set the maximum number of loops allowed
> (similar to max_trace value). POV would then only need to keep track of the
> number of iterations the current loop has gone through and kick it out when it
> reaches the limit, rather than tracking any number of variables.
That sounds like an option.
I'm not sure though whether it would be superior to just waiting for the user to
decide that it was about time for the parsing to finish.
> I would
> expect that POV would also report an error (without aborting) to the message
> window that a loop was terminated with the line number for debugging purposes.
I disagree. Just dropping out of a loop before all conditions have been
established that might be presumed by the following code may mess up, and in
some cases (software using #write) actually have the potential to mess up data.
Maybe just printing a debug info but continuing with the loop would be the most
sensible thing to do; if the user finds that it doesn't make sense to keep the
loop going, he can abort the render anytime.
> The one disadvantage to this is that it would be globaL and apply to all loops
> within the scene.
I don't see a problem with that. Of couse you could specify a max iteration
thing per loop, but then again that would be quite redundant in the cases it's
most needed.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"clipka" <nomail@nomail> wrote:
> "Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> > Perhaps the easiest and most universal solution to implement would be to add a
> > global "loop_limit" variable that would set the maximum number of loops allowed
> > (similar to max_trace value). POV would then only need to keep track of the
> > number of iterations the current loop has gone through and kick it out when it
> > reaches the limit, rather than tracking any number of variables.
>
> That sounds like an option.
>
> I'm not sure though whether it would be superior to just waiting for the user to
> decide that it was about time for the parsing to finish.
>
It would give the user the advantage of pointing out the offending loop.
>
> > I would
> > expect that POV would also report an error (without aborting) to the message
> > window that a loop was terminated with the line number for debugging purposes.
>
> I disagree. Just dropping out of a loop before all conditions have been
> established that might be presumed by the following code may mess up, and in
> some cases (software using #write) actually have the potential to mess up data.
>
>
> Maybe just printing a debug info but continuing with the loop would be the most
> sensible thing to do; if the user finds that it doesn't make sense to keep the
> loop going, he can abort the render anytime.
>
This is true assuming that the user does not want an infinite loop situation at
all.
There are circumstances where the user may want the loop to continue until it
reaches an assumed infinite loop and then jump the loop and get on with the
render.
For example, the non-intersecting spheres in a box scenerio I described before.
The user may want as many spheres as possible to fit in the box, but does not
really know the practical limit. (I know this scenario could be handled with a
large for loop or by other means, but it is meant as a simple demonstration of
an intended situation)
>
> > The one disadvantage to this is that it would be globaL and apply to all loops
> > within the scene.
>
> I don't see a problem with that. Of couse you could specify a max iteration
> thing per loop, but then again that would be quite redundant in the cases it's
> most needed.
I agree it wouldn't likely be a problem in most circumstances.
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> I do agree that a for loop would be more concise and I'm not trying to hinder
> you from getting it. It was more a matter of showing that adding a #for
> wouldn't add functionality that the current #while loop can't already do, it
> just makes things more concise and recognizable, and perhaps easier to use (in
> my earlier days I often wished I did have a for loop, however now, I just got
> used to using the while loop). If whatever programming overhead involved in
> adding #for loop functionality is worth the value of having it, then, by all
> means, it could/should be added. The value being in simpler coding rather than
> added functionality.
Ah, so then it seems we're actually of the same opinion.
The fact that from a functionality point of view, a #while() loop is perfectly
fit to be used instead of a #for loop (or any other possible loop for that
matter) is not much news to me though - and given how it's introduced in the
POV-Ray manual I'd be surprised if it was news to any significant number of
people, so I naturally assumed you were doubting its added value.
> An example is placing non-intersecting spheres in a box. If the maximum count
> is greater than what can actually fit in the volume (i.e., the loop reaches a
> point where it can no longer find a big enough space to place a new sphere, but
> keeps trying because the max number of objects hasn't been reached), an inifnite
> loop will be encountered. This only a simple demonstration as, in reality, it
> should be obvious what is causing the inifinite loop once it is located,
> however, the presence of the inifinite loop would not (likely) be obvious by
> simple examination of the written code (i.e. it is not a coding error).
Okay, that's a different point though. Note however that this is a perfect
example for where code analysis would come to its limits identifying the
endless loop; after all, it's not an issue of code structure but a geometrical
one, and you cannot come up with an algorithm to solve every possible such
decision. Even worse, what if there would theoretically be just enough space
for another such a sphere, but the random number generator happens to never
ever produce the respective position with the given seed?
So in this case it's up to the developer to think of a suitable upper bound when
to terminate the loop, and design it right into it:
#declare SpheresPlaced = 0;
#declare i = 0; #while ((Spheres < MaxSpheres) & (i < MaxLoops))
...
#if (Whatever)
...
#declare Spheres = Spheres + 1;
// maybe also #declare i = 0;
#end
...
#declare i = i + 1; #end
Something like this. I don't think there's much that will save you from putting
this kind of thought into a non-straightforward counting loop.
I guess an interesting syntax for such constructs would be something like this:
#for Spheres = 1 to 10000
...
#if (Whatever)
...
#else
#retry 10 // new keyword, in addition to the #for keyword
#end
#end
which would be to say, if the condition does not hold true, abort the current
iteration and re-iterate without incrementing the counter - unless you tried 10
times in a row without success already, in which case abort the loop.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> Adding the #for loop only solves the problem with a misplaced or missing
> increment statement, which is purely a programmer's error that can be largely
> avoided with a little diligence by the programmer. Of course this is the type
> of infinite loop scenerio that the OP is referring to.
>
> This will not solve other infinite loop problems that are not related to
> programmer error such as conditional statements that are never satisfied due to
> some issue that is not superficially apparent.
Those, to, by definition are programmer errors, BTW.
> The #for loop would add some ease and conciseness to the coding end and help
> users avoid this programming error, but it would not add any functionality
> overall that isn't already achievable through a properly constructed #while
> loop.
*No* loop does. #while() is perfectly able to save it all, when properly
combined with #if() constructs.
Like with #for loops, the corresponding #while replacement may become
cumbersome, but it's perfectly possible.
> One further item on the potential creation of #for loops: Would they be best
> end-bracketted with the general #end statement (as #while, #if, #switch and
> #macro all use)? Or would it be more appropriate to add a "#next" statement or
> even "#next n" statement instead? #end would make it more consistent with
> current programming practice, but #next would make the #for loop construct more
> visible and identifiable.
Whith all other statements bracketed with #end, for consistency's sake there's
virtually no other way as to close them with #end, too. And why not?
Sure, a "#next i" statement helps identify the "#for" statement it belongs to,
but then again you can achieve the same through good indentation, or using
"#end // i".
> Along this line of thinking, perhaps more specific
> #end statements would also be more appropriate for the other situations as
> well: #while/#wend, #if/#endif, #switch/(#send?), #macro/(#mend?). Of course
> you would likely keep the #end functionality for backwards compatibility.
I'd personally favor completely different bracketing rules anyways, using {}
instead (to use the same bracketing rules as for object statements, and
functions for that matter). Though I know various people (I don't dare make any
estimate here) would disagree.
I don't think a #wend, #send, #mend etc. is really necessary, and #endif would
make this inconsistent anyway.
If at all (there is a bit of a point here to identify the type of statement that
you expect to be ending, so as to enable the parser to better pin down where you
goofed the #end matching), I'd rather go for "#end if", "#end macro" etc.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> How can the checker know that the result is different each time the macro
> is called?
It doesn't, it just assumes it is to avoid a false positive situation.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
A further thought I had this morning rather than adding an *infinite* loop
checker or loop_limit variable.
Typically if a render is parsing too long and a user gets suspicious, the user
will terminate the program. Currently this simply posts the message "Render
cancelled by user." plus stats. It would maybe be of debuggin assistance to
also report the line number where parsing was at the time of interruption
(similar to how an error does) and also (if it may be possible) the current
number of iterations the current loop(s) have been through. You would likely
want it to report the number of iterations for any currently active loop (in
the case of nested loops) as it could be any of them that are the issue, not
just the most recent (any closed or inactive loops can be ignored).
EG:
01 #declare i=0;
02 #while (i<10)
03 #declare i=i+1;
04 #end
05 #declare i=0;
06 #while (i<100)
07 #declare j=0;
08 #while (j<100)
09 #declare j=j+1;
10 #end
11 #end
The user breaks the program while it is at line 09.
The first loop is inactive [line 2: #while (i<10)] as it reached its #end
statement, but the next two loops [line 6: #while (i<100), line 8: #while
(j<100)] are currently active, however POV doesn't know which is the problem
(the user should be able to tell that the j loop is fine as it has its counter,
but the i loop is infinite as the counter was forgotten.
In this case, POV could report (similar to error reporting) something along the
lines of:
Render cancelled by user.
Break point:
File: C:\POVDIR\POVFILE.pov Line: 9
#declare j=j+1;
Active loop:
File: C:\POVDIR\POVFILE.pov Line: 6
#while (i<100)
Iteration count: 12345
Active loop:
File: C:\POVDIR\POVFILE.pov Line: 8
#while (j<100)
Iteration count: 67
The user can reference this to see where the file was terminated (line 9) and
the iteration count of the current active loops (line 6: 12345, line 9: 67) and
pinpoint the problem. From this the user can infer that it may be the line 6
loop that is the problem as it has gone through a larger number of iterations
(perhaps larger than should be expected), whereas the line 8 loop is within the
expected loop count still. Further investigation would reveal the omitted i
increment statement causing the infinite loop.
All this would be done with breaking the current implementation of the SDL. It
would simply require reporting of the current line (which should be easy as it
is already done for errors) plus the addition of loop counters. I'm not
familiar with the code, but I should think it wouldn't be an overly difficult
task to add this as POV would already need to keep track of open loops within
it's code parsing.
Any thoughts?
-tgq
-tgq
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Trevor G Quayle" <Tin### [at] hotmail com> wrote:
> Render cancelled by user.
> Break point:
> File: C:\POVDIR\POVFILE.pov Line: 9
> #declare j=j+1;
> Active loop:
> File: C:\POVDIR\POVFILE.pov Line: 6
> #while (i<100)
> Iteration count: 12345
> Active loop:
> File: C:\POVDIR\POVFILE.pov Line: 8
> #while (j<100)
> Iteration count: 67
Nice one. That would indeed be handy.
> I'm not
> familiar with the code, but I should think it wouldn't be an overly difficult
> task to add this as POV would already need to keep track of open loops within
> it's code parsing.
I haven't paid much attention to loop handling yet, but nested loops are handled
by recursive calls, and I guess aborting parsing is done by throwing an
exception; so it would mean adding...
- a local variable to count loop iterations while in a loop
- code to catch the exception while in a loop, and throw it onward with added
information about the current loop
- code to pass the detailed information to the front-end
- code in the front-end to output the information
Nothing that sounds dramatically complicated.
Being on it, it would be nice to have the same mechanism kick in if parsing is
aborted for any other reason.
Another thing that would greatly faciliate debugging would be a simpler syntax
to output a single variable, so that for instance
#declare Foo = 47.11000;
#local Bar = sphere { <0,0,0>, 1 }
#debug_var Foo, Bar
#debug_var Foobar
might print:
Foo (global): 47.11
Bar (local): object
Foobar: undefined
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Nicolas Alvarez
Subject: Re: I want to be rid of my stupid mistakes
Date: 20 Aug 2009 02:52:47
Message: <4a8cf2bf@news.povray.org>
|
|
 |
|  |
|  |
|
 |
clipka wrote:
> "scott" <sco### [at] scott com> wrote:
>> I'm not saying it's possible to detect whether any program will stop or
>> not. I'm saying that in *some* cases you can relatively easily detect
>> that it won't stop without changing the functionality.
>
> I'm definitely repeating myself here: Those easy cases would come packaged
> with too many not-so-easy special cases.
>
> Sure you can detect a simple
>
> #while (i < N)
> //#declare i=...
> #end
>
> as being an infinite loop, but that's an absolutely trivial case; as soon
> as you go from there to
>
> #while (i < N)
> ...
> //#declare i=...
> ...
> #end
>
> then if you don't find a "#declare i=...", you *must* examine the "..."
> thoroughly before you can conclude that the user really forgot it.
>
> Of course, if you *do* find a "#declare i=..." in there, you can tell for
> sure the user did *not* forget it; but that doesn't get us any further.
>
> The bottom line is that a potentially-infite-loop detector would be a
> quite complex piece of code, even if it were just to catch some standard
> cases. There would be much easier and more useful remedies for the
> forgotten-increment ailment.
I think most of the cases previously posted here are actually solvable. That
is, you can avoid thinking it's infinite when it's not (you can't avoid the
opposite, but it's OK, we don't have to detect all cases, and it's
impossible anyway). I have yet to see someone post a convincing code
snippet that would give a false positive.
#declare I=0;
#while (I < Limit)
//...
#end
If neither 'I' nor 'Limit' are ever mentioned inside the loop, it's
infinite. Otherwise, it may be infinite, but assume it's not and let it
run.
#declare I=0;
#while (I < Limit)
//...
#include "file.inc"
#end
Just assume it's not infinite if there is an include, since it's prone to
way too many variables. For example, the user could edit file.inc in the
middle of the parsing to have #declare I=Limit;
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Nicolas Alvarez schrieb:
> #declare I=0;
> #while (I < Limit)
> //...
> #end
>
> If neither 'I' nor 'Limit' are ever mentioned inside the loop, it's
> infinite.
Not necessarily:
#macro Next()
#declare I=I+1;
#end
#declare I=0;
#while (I < Limit)
Next()
#end
No mention of I anywhere in the loop, yet perfectly finite.
You *must* dig into *every* macro to catch this.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> #macro Next()
> #declare I=I+1;
> #end
>
> #declare I=0;
> #while (I < Limit)
> Next()
> #end
>
> No mention of I anywhere in the loop, yet perfectly finite.
>
> You *must* dig into *every* macro to catch this.
The parser re-parses the macro every time it is called though, doesn't it?
So the parser simply needs to look out for any "#declare I" any time it is
parsing commands within the loop, no matter if it is in a macro or not.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] scott com> wrote:
> > #macro Next()
> > #declare I=I+1;
> > #end
> >
> > #declare I=0;
> > #while (I < Limit)
> > Next()
> > #end
> >
> > No mention of I anywhere in the loop, yet perfectly finite.
> >
> > You *must* dig into *every* macro to catch this.
> The parser re-parses the macro every time it is called though, doesn't it?
> So the parser simply needs to look out for any "#declare I" any time it is
> parsing commands within the loop, no matter if it is in a macro or not.
It doesn't necessarily parse it every time. You could have something like:
#declare I=0;
#while (I < Limit)
#if(rand(someSeed) < 0.5)
Next()
#end
#end
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> It doesn't necessarily parse it every time. You could have something
> like:
>
> #declare I=0;
> #while (I < Limit)
> #if(rand(someSeed) < 0.5)
> Next()
> #end
> #end
Ah yes, I think the conclusion we came to before is that anything that
involves macro calls has to be assumed finite, because as clipka said you
would need to search all macros to see if 'I' was redefinied anywhere, and
that seems a bit wasteful.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |