The Persistence of Vision Raytracer (POV-Ray).
This is the legacy Bug Tracking System for the POV-Ray project. Bugs listed here are being migrated to our github issue tracker. Please refer to that for new reports or updates to existing ones on this system.
Opened by Juha Nieminen - 2010-03-22
Last edited by Christoph Lipka - 2010-06-19
FS#84 - A for-loop construct
Many people clearly miss a simple for-loop construct in povray. It is indeed true that probably at least 99% of #while loops out there have the form of a simple for-loop. It’s much rarer to have to use more exotic forms of looping supported by the #while mechanism. Thus it would make sense if a #for construct would be added which would make writing such loops much easier and convenient.
The only remaining question would be the syntax.
IMO the for-loop construct should implicitly declare a local variable of a specified name, automatically increment it during the loop, and then undefine it after the loop ends. It could perhaps be something along the lines of:
#for(<identifier name>, <initial value>, <final value> [, <step>]) <loop body> #end
Example:
#for(Counter, 1, 10) // 'Counter' gets values 1, 2, 3, ..., 10 #debug concat(str(Counter, 0, 0), "\n") #end #for(Counter, 1, 10, 3) // 'Counter' gets values 1, 4, 7, 10 #debug concat(str(Counter, 0, 0), "\n") #end
I think this syntax ought to be relatively easy to implement (compared to more “traditional” syntaxes, such as something like “for Counter = 1 to 10” or the C syntax, which would be a lot more complicated).
Of course this raises a couple of questions:
1) What happens if ‘Counter’ was already declared as an identifier? One of three possibilities comes to mind:
- The ‘Counter’ in the for-loop replaces the previous identifier, as a regular #local command would.
- The ‘Counter’ in the for-loop hides the identifier for the duration of the loop, and unhides it afterwards.
- A syntax error is given (ie. the identifier name must be unused).
2) Should the user be able to modify the counter variable from inside the body of the loop? Something like this comes to mind as viable:
// Prints the values 1, 2, 3, 9 and 10 #for(Counter, 1, 10) #debug concat(str(Counter, 0, 0), "\n") #if(Counter = 3) #local Counter = 8; #end #end
Alternatively the counter variable could be read-only.
Additionally, it could be nice if #break could be used to immediately jump out of the current loop (either #while or #for).
Saturday, 19 June 2010, 00:59 GMT
Reason for closing: Implemented
Additional comments about closing:
No beta tester feedback for way over a
month now; I consider that good news.
I fully second this feature request.
As for the details, for simplicity as well as consistency with current practice I'd advocate a #for loop to be fully equivalent to a corresponding #while loop, i.e. that the following have exactly the same effects and side-effects inside and after the loop:
One more thing: If the final value is smaller than the initial value, the counter could go backwards automatically. The sign of the optional step value could be ignored (in other words, a step value of 3 and a step value of -3 would be completely identical, as the sign is ignored). This way you could write:
Making the loop "direction" depend on the bounds is a bad idea, as it is frequently desired that the loop not be executed if end < start, as demonstrated by the following typical use pattern:
To my knowledge, virtually all programming languages do not auto-adjust the loop direction.
Implemented with change #4941.
Implemented #break statement with change #4942.