This proposal is intended to use the loops2 suggestion and change it slightly for easier foreach's
Loops have the following form:
IM IN YR <label> [EATING UR <target>] [TIL|WILE <expression>] <code block> IM OUTTA YR <label|target>
An in-scope identifier is an identifier that has been declared and is accessible within the current scope of the execution.
A containing loop is a loop that contains the statement that is being discussed. That is, the statement falls between the loop start and loop end.
A loop is initialized with the syntax IM IN YR <label> and is terminated with IM OUTTA YR <label>.
The loop initialization and termination statements surround any number of statements (including zero). The statements are executed from the beginning of the loop until the end of the loop is reached or the execution breaks out of the loop.
When execution reaches the end of a loop (OUTTA), it begins again at the start of the loop, repeating indefinitely until the escape condition is met or the execution breaks out.
Loops can be nested within each other, like so:
IM IN YR LOOP
...
IM IN YR INNER_LOOP
...
IM OUTTA YR INNER_LOOP
...
IM OUTTA YR LOOP
If an inner loop does not terminate before the termination of the outer loop, the loop terminates there.
IM IN YR LOOP
...
IM IN YR INNER_LOOP
...
IM OUTTA YR LOOP, BTW ALL INNER LOOPS ALSO TERMINATE.
The labels can be existing variables or are new variables created for the scope of the loop. The loop will exit if the variable is null.
IM IN YR WIKIPEDIA
...
WIKIPEDIA R "", BTW THE LOOP EXITS.
IM OUTTA YR WIKIPEDIA
If a BUKKIT is a label then the loop will iterate through the BUKKIT's keys until the BUKKIT is null. I assume that the BUKKIT Spec will include a defualt iterator. If the BUKKIT is unable to iterate, then the interpreter should generate an error. The current value in the BUKKIT is placed in the variable specified by EATIN UR <target> or IT.
File Handles (I assume some variable handles an open file? If you want I can write a spec for it.) are treated like BUKKITS. Each newline is placed in either the variable specified by EATIN YR <variable> or in IT. The loop exits by default at EOF.
BTW THIS IS A FOREACH LOOP BTW PRINTS OUT EACH VALUE IN WIKIPEDIA. IM IN YR WIKIPEDIA EATIN UR ARTICLES ... VISIBLE ARTICLES ... IM OUTTA YR WIKIPEDIA
Loop execution can be broken with the command GTFO. This causes execution of the innermost enclosing loop to cease and program execution begins immediately after that loop's terminator (OUTTA).
GTFO can be optionally followed by a valid loop label for any containing loop. Doing so will cause execution of the named loop to cease as well as any nested loops that were currently being executed. The execution continues immediately after the named loop's terminator.
Using GTFO with an out-of-scope identifier is illegal, as is using GTFO with an identifier for a loop that doesn't contain that GTFO.
WHATEVER can be used to stop execution of the statements in the innermost enclosing loop and move execution to the terminating statement of the loop.
If a function or mathematical operation is used as the label, then the loop either places the value in IT or in the variable specified by EATIN. The label used by the OUTTA declaration is the return variable of the function.
BTW A FOR LOOP.
IM IN YR SUM OF X AND 1
IM IN YR MYFUNK IT EATIN UR PAGE
VISIBLE PAGE
IM OUTTA YR PAGE
IN OUTTA YR IT
A newly declared loop variable (with YR) uses the same scoping rules as normal variables. It is effectively declared right before the loop starts and is available to the conditional. It is still accessible after the termination of the loop.
A previously declared variable has the scope of its original declaration. It may be accessible after the termination of a loop.
Variables declared within the loop block are scoped to the block and cease to exist after a single iteration of the loop (after hitting IM OUTTA or WHATEVER). They are not accessible in the conditional or after the termination of a loop. This is currently under discussion.
The initialization statement can contain a conditional expression. There are two types, TIL and WILE.
WILE causes the loop to execute as long as the expression evaluates to WIN (boolean true); that is, while the expression is true.
TIL causes the loop to execute as long as the expression evaluates to FAIL (boolean false); that is, until the condition is true.
In each case, the condition is checked before execution of the enclosed statements. This means that if the condition is met before the loop statements even execute, they will not execute.
If no variable is associated with the loop, an expression that results in a non-boolean result will be cast to a boolean value.
If a variable is associated with the loop an expression that does not result in a boolean result will, as a shorthand, evaluate as an implied BOTH SAEM <loop-var> AN <expression>. In the case of WILE, the loop will execute as long as the loop-var is equal to the value of the expression, and in the case of TIL the loop will execute as long as the loop-var is not equal to the value of the expression.