Loops are pretty important, and Lua loops are a bit different than what you'll find in similar languages. Some further clarification is in order.
As before, the Lua 5.3 reference manual explains everything in depth, although in kind of a dry, technical way.
Most of the small chunks of Lua code below can be copied and pasted into the Foldit recipe editor for a quick test. Select "New (ScriptV2)" to get a blank recipe, paste in the code, and click "Run". You'll need to close the recipe editor to view the recipe output window. The Foldit recipe editor fine for this type of light tinkering.
Loops, loops, loopsEdit
As mentioned in the main tutorial, there at least three kinds of looping in Lua:
The for loop example in the tutorial looked like this:
segCnt = 95 buildLen = 3 for ii = 1, segCnt - buildLen + 1, buildLen do print ( "range = " .. ii .. " - " .. ii + buildLen - 1 ) end
The variable segCnt is added here to make things a little clearer.
This loop selects ranges 1 to 3, 4 to 6, 7 to 9, and so on.
It's possible to get the same results using the other types of loop, for example a while loop:
segCnt = 17 buildLen = 3 ii = 1 while ii <= segCnt - buildLen + 1 do print ( "range = " .. ii .. " - " .. ii + buildLen - 1 ) ii = ii + buildLen end
Or a repeat-until loop:
segCnt = 17 buildLen = 3 ii = 1 repeat print ( "range = " .. ii .. " - " .. ii + buildLen - 1 ) ii = ii + buildLen until ii <= segCnt - buildLen + 1
These types of loops are really equivalent, but usually the for loop is the first choice when you're working numeric ranges, like segment numbers in Foldit.
More "for": scopeEdit
The variable "ii" in this example is little special. It's available only inside the for loop. This makes ii a local variable, one which has limited scope.
By default in Lua, any variable is global, meaning that any it's available in any function or block of code. This is different than other languages, which often require you to specifically declare variables as global.
Global variables are fine for small recipes, but some Foldit recipes can be several thousand lines long. Globals can become a problem. Accidentally reusing the same variable name in two different functions can cause bugs that are difficult to find.
Adding the keyword "local" before a variable means the variable only exists within the same function or block of code. The recipe in this tutorial could have said "local segCnt" and "local buildLen", but it really wouldn't matter, since it's all one block of code at this point.
Having loop counters like ii be automatic local variables is big help, since many recipes have a lot of similar loops. You'll sometimes see this:
local ii for ii = 1, 10 do print ( ii ) end
All this does is create another variable "ii". The for loop has its own separate "ii", which vanishes when the for loop completes. The "ii" from "local ii" is left unchanged. Try this example:
local ii = -32767 for ii = 1, 10 do print ( ii ) end print ( ii )
Side note: naming loop counters "i", "j", and "k" has been a tradition since the days of FORTRAN, but the author likes to double up and use "ii", "jj", and "kk" instead. It's a lot easier to find "ii" in your text editor than just plain "i"....
In Lua, you don't have to specify the increment or step. By default, a value of 1 is used. So
for ii = 1, 10 do print ( ii ) end
Prints the numbers from 1 to 10.
Also, the step can be negative, in which case it becomes a decrement. So, if you want to launch rockets:
for ii = 10, 0, -1 do print ( ii ) end print ( "blastoff!")
Give that a try, then try leaving off the -1.