Loop structures: Difference between revisions
(→[[C]]: Added syntax highlighting) |
imported>Maleza No edit summary |
||
(209 intermediate revisions by 75 users not shown) | |||
Line 1: | Line 1: | ||
{{DeprecatedTask}} |
|||
{{Control Structures}} |
|||
[[Category:Maintenance]]In this former task, we document loop structures offered by different languages. |
|||
{{Task}} |
|||
;What are loops?: |
|||
In this task, we document loop structures offered by different languages. |
|||
Loops are control structures that allow sections of code to be executed repeatedly according to the controlling conditions of the loop. |
|||
==[[Ada]]== |
|||
[[Category:Ada]] |
|||
There are two types of loops: |
|||
===Simple Loop=== |
|||
The simple loop in Ada produces an infinite loop. |
|||
;Repetition: |
|||
loop |
|||
Additionally, there is the overly simple repetitive loop: [[repeat|repetition]]. The simplistic construct executes a block of code, or a procedure, a given number of times, without explicitly exposing any state change to the looped procedure. |
|||
-- do something |
|||
end loop; |
|||
;Iterative loops: |
|||
Any loop can be terminated by the ''exit'' reserved word. |
|||
loop |
|||
An [[:Category:Iteration|iterative loop]] repeatedly executes a set of instructions as the iterator steps through a series of values. Types of iterative loops include [[for loop]]s and [[foreach]] loops. An iterative loop is a repetition but with a variable dependent on the current iteration. This allows the looped procedure to vary slightly between iterations. For example, the same operation can be carried out on each iteration, but each time on a different object. |
|||
-- do something |
|||
if some-condition then |
|||
;Conditional loops: |
|||
exit; |
|||
A [[conditional loop]] tests for a condition around the loop, and repeatedly executes a block of [[instruction]]s whilst the [[condition]] is true. Types of [[conditional loop]]s include [[while loop]]s and [[do-while loop]]s. |
|||
end if; |
|||
-- do somthing else |
|||
'''Examples here should be migrated to an appropriate [[:Category:Iteration|Iteration]] page and removed from here. If a page does not exist demonstrating a particular loop structure, discuss it [[:Category talk:Iteration|here]].''' |
|||
end loop; |
|||
<br><br> |
|||
The short-hand notation for expressing the exit condition is: |
|||
=={{header|68000 Assembly}}== |
|||
loop |
|||
'''NOT COVERED IN LOOP PAGES''' |
|||
-- do something |
|||
exit when some-conditon; |
|||
The 68000 uses <code>DBxx Dn, label</code> for loop counting. "Dn" refers to a chosen data register. The "xx" is replaced with the condition code of your choice (<code>DBRA</code> stands for Decrement, Branch Always which is most commonly used). Execution will jump to the labeled line of code unless Dn's lower two bytes equal #$FFFF or the specified condition code is true, whichever occurs first. Keep in mind that the condition code has nothing to do with the value stored in Dn; rather, it represents the outcome of the operation just before the branch. This is similar to a "repeat until" construct in some other languages. |
|||
-- do something else |
|||
end loop; |
|||
The below code snippet represents a loop that continues until a value greater than 3500 is read. However, it will also end after the 2000th iteration automatically, regardless of whether the condition is ever met. |
|||
===While loop=== |
|||
while some-condition loop |
|||
<syntaxhighlight lang="68000devpac"> |
|||
-- do something |
|||
MOVE.W #1999,D1 ;DBxx loop counters need to be pre-decremented to work properly, since they terminate at $FFFF rather than 0 |
|||
end loop; |
|||
LOOP: |
|||
===For loop=== |
|||
MOVE.W (A0)+,D0 |
|||
The ''for'' loop in Ada iterates over a specified range of discrete values. Ranges are an important concept in Ada. Ranges are always expressed in the form of lowest..highest. The loop control variable always takes on the type of the specified range. The loop control variable is read-only within the loop, and has a scope only within the loop. |
|||
CMP.W #3501,D0 ;COMPARE TO #3501 |
|||
DBCC D1,LOOP ;DECREMENT, BRANCH UNTIL CARRY CLEAR OR D1 = #$FFFF |
|||
</syntaxhighlight> |
|||
=={{header|AmbientTalk}}== |
|||
===doTimes=== |
|||
<syntaxhighlight lang="ambienttalk"> |
|||
// print 1 2 3 ... 20 |
|||
20.doTimes { |i| system.print(" "+i); } |
|||
</syntaxhighlight> |
|||
===each=== |
|||
Iterate over a collection: |
|||
<syntaxhighlight lang="ambienttalk"> |
|||
[ "foo", "bar", "baz" ].each: { |e| |
|||
system.print(" "+e); |
|||
} |
|||
// prints: foo bar baz |
|||
</syntaxhighlight> |
|||
Iteration over a literal range: |
|||
for I in 1..10 loop |
|||
Put(I); |
|||
end loop; |
|||
You can also employ a range defined earlier in your code. |
|||
subtype Month_Number is Integer range 1..12; |
|||
for I in Month_Number loop |
|||
Put(I); |
|||
end loop; |
|||
Ranges are also defined for the indices for arrays. Ada array indices can begin at any value, not just 0 or 1. |
|||
type Balanced_Index is range -10..10; |
|||
type My_Array_Type is array(Balanced_Index) of Integer; |
|||
My_Array : My_Array_Type; |
|||
for I in My_Array'Range loop |
|||
Put(My_Array(I)); |
|||
end loop; |
|||
==[[AppleScript]]== |
==[[AppleScript]]== |
||
'''NOT COVERED IN LOOP PAGES''' |
|||
[[Category:AppleScript]] |
|||
===repeat-until=== |
===repeat-until=== |
||
<syntaxhighlight lang="applescript> |
|||
set i to 5 |
|||
set i to 5 |
|||
repeat until i is less than 0 |
|||
repeat until i is less than 0 |
|||
set i to i - 1 |
|||
end repeat |
|||
end repeat |
|||
repeat |
|||
--endless loop |
|||
end repeat |
|||
</syntaxhighlight> |
|||
===repeat-with=== |
===repeat-with=== |
||
<syntaxhighlight lang="applescript> |
|||
repeat with i from 1 to 20 |
|||
repeat with i from 1 to 20 |
|||
--do something |
|||
--do something |
|||
end repeat |
|||
set array to {1,2,3,4,5} |
|||
repeat with i in array |
|||
display dialog i |
|||
end repeat |
|||
</syntaxhighlight> |
|||
==[[AssemblyScript]]== |
|||
'''NOT COVERING ALL POSSIBLE LOOP OPTIONS''' |
|||
==[[C]]== |
|||
[[Category:C]] |
|||
===while=== |
===while=== |
||
<syntaxhighlight lang="javascript"> |
|||
'''Compiler:''' [[GCC]] 4.1.2 |
|||
let done = false |
|||
while (!done) { |
|||
done = true |
|||
} |
|||
</syntaxhighlight> |
|||
===do while=== |
|||
<highlightSyntax language=C> |
|||
<syntaxhighlight lang="javascript"> |
|||
int main (int argc, char ** argv) { |
|||
let done = false |
|||
int condition = 1; |
|||
do { |
|||
done = true |
|||
} while (!done) |
|||
// Do something |
|||
</syntaxhighlight> |
|||
// Don't forget to change the value of condition. |
|||
// If it remains nonzero, we'll have an infinite loop. |
|||
} |
|||
} |
|||
</highlightSyntax> |
|||
===do-while=== |
|||
<highlightSyntax language=C> |
|||
int main (int argc, char ** argv) { |
|||
int condition = ...; |
|||
do { |
|||
// Do something |
|||
// The difference with the first loop is that the |
|||
// code in the loop will be executed at least once, |
|||
// even if the condition is 0 at the beginning, |
|||
// because it is only checked at the end. |
|||
// Don't forget to change the value of condition. |
|||
// If it remains nonzero, we'll have an infinite loop. |
|||
} while ( condition ); |
|||
} |
|||
</highlightSyntax> |
|||
===for=== |
===for=== |
||
<syntaxhighlight lang="javascript"> |
|||
<highlightSyntax language=C> |
|||
for (let i = 0; i < 10000; i++) { |
|||
int main (int argc, char ** argv) { |
|||
i += i |
|||
} |
|||
</syntaxhighlight> |
|||
for {i=0; i<10; ++i) { |
|||
// The code here will be performed 10 times. |
|||
// The first part in the for-statement (i=0) is the initialization, |
|||
// and is executed once before the loop begins. |
|||
// The second part is the end condition (i<10), which is checked |
|||
// every time the loop is started, also the first time; |
|||
// the loop ends if it is false. |
|||
// The third part (++i) is performed every time the code in the loop |
|||
// is at the end, just before the end condition is checked. |
|||
} |
|||
} |
|||
</highlightSyntax> |
|||
==[[Brainf***]]== |
|||
===while with continue=== |
|||
'''NOT EXPLAINED THIS MUCH IN LOOP PAGES''' |
|||
The continue statement allows you to continue execution |
|||
BF's only control flow construct of any kind is a loop. Two of the eight commands define the start and end of a conditional loop. |
|||
* '''[''' - branch forward past matching ']' if the current cell is zero |
|||
In C you can only do this with the most inner loop. |
|||
* ''']''' - branch back to the matching '[' if the current cell is non-zero |
|||
You can also do this with do-while and for. |
|||
In practice this is equivalent to a "while not zero" loop in other languages. |
|||
[-] set current cell to zero |
|||
[->+>+<<]>>[-<<+>>] copy cell 0 to cell 1, using cell 2 as temporary storage |
|||
<highlightSyntax language=C> |
|||
int main (int argc, char ** argv) { |
|||
int condition = 1; |
|||
while ( condition ) { |
|||
// Do something |
|||
if (other condition) |
|||
continue; // Continue at the beginning of the loop |
|||
// Do something else |
|||
// This part is not executed if other condition was true |
|||
} |
|||
} |
|||
</highlightSyntax> |
|||
==[[C++]]== |
|||
===while with break=== |
|||
=== Compile-Time Control Structures === |
|||
The break statement allows you to stop a loop. |
|||
'''Necessary?''' |
|||
In C you can only break from most inner loop. |
|||
A compile-time for loop can be generated with template metaprogramming. Example: |
|||
You can also do this with do-while and for. |
|||
<syntaxhighlight lang="cpp"> |
|||
<highlightSyntax language=C> |
|||
// the loop |
|||
int main (int argc, char ** argv) { |
|||
template<int start, int finish, template<int n, typename T> class X> struct loop |
|||
int condition = 1; |
|||
{ |
|||
typedef typename X<start, typename loop<start+1, finish, X>::type>::type type; |
|||
}; |
|||
// the termination of the loop |
|||
while ( condition ) { |
|||
template<int finish, template<int n, typename T> class X> struct loop<finish, finish, X> |
|||
// Do something |
|||
{ |
|||
typedef typename X<finish, void>::type type; |
|||
}; |
|||
// example usage: This implements just a very complicated way of building a multi-dimensional array |
|||
// the loop body |
|||
if (other condition) |
|||
template<int n, typename T> struct build_array |
|||
break; // Continue after the the loop |
|||
{ |
|||
typedef T type[n]; |
|||
}; |
|||
template<int n> struct build_array<n, void> |
|||
// Do something else |
|||
{ |
|||
// This part is not executed if other condition was true |
|||
typedef double type; |
|||
} |
|||
}; |
|||
</highlightSyntax> |
|||
// the loop execution: This is equivalent to |
|||
// typedef double array_type[2][3][4][5]; |
|||
typedef loop<2,6,build_array>::type array_type; |
|||
</syntaxhighlight> |
|||
==[[ |
==[[Clojure]]== |
||
'''NOT COVERED IN LOOP PAGES''' |
|||
[[Category:C plus plus]] |
|||
===loop=== |
|||
=== Run-Time Control Structures === |
|||
<syntaxhighlight lang="clojure"> |
|||
;; loop/recur is the most general looping construct |
|||
(loop [lst [1 3 5 7] |
|||
ret []] |
|||
(if lst |
|||
(recur (rest lst) (conj ret (* (first lst) (first lst)))) |
|||
ret)) |
|||
==> [1 9 25 49] |
|||
</syntaxhighlight> |
|||
=={{header|Crack}}== |
|||
==== for ==== |
|||
===For=== |
|||
'''Compiler:''' [[GCC]] 3.3.4 |
|||
<syntaxhighlight lang="crack"> |
|||
#include <iostream> |
|||
for( i=0; i<9; i++) |
|||
cout ` $i\n`; |
|||
int main() |
|||
</syntaxhighlight> |
|||
{ |
|||
int i = 1; |
|||
// Loops forever: |
|||
for(; i == 1;) |
|||
std::cout << "Hello, World!\n"; |
|||
} |
|||
=={{header|Curto}}== |
|||
===do-while=== |
|||
===HACER-BUCLE=== |
|||
'''Compiler:''' [[GCC]] 4.1.2 |
|||
<syntaxhighlight lang="curto"> |
|||
int main (void) { |
|||
\ limite inicio HACER sentencias iteradas BUCLE |
|||
int condition = 1; |
|||
\ limite inicio HACER sentencias iteradas incremento +BUCLE |
|||
\ SALIR \ abandona bucle HACER |
|||
do { |
|||
\ DBUCLE SALIR \ limpia contadores de la pila de retorno antes de abandonar la palabra actual |
|||
// Do something |
|||
</syntaxhighlight> |
|||
// Don't forget to change the value of condition. |
|||
// If it remains nonzero, we'll have an infinite loop. |
|||
} while ( condition ); |
|||
} |
|||
ejemplo: Dos iteraciones típicas |
|||
[[Category:C plus plus]] |
|||
<syntaxhighlight lang="curto"> |
|||
=== Run-Time Control Structures === |
|||
10 0 hacer i . bucle \ Imprime números de 0 a 9 |
|||
10 0 hacer i . 2 +bucle \ Imprime números pares de 0 a 8 |
|||
</syntaxhighlight> |
|||
===EMPEZAR-HASTA=== |
|||
<syntaxhighlight lang="curto"> |
|||
\ EMPEZAR sentencias iteradas condicional HASTA |
|||
</syntaxhighlight> |
|||
ejemplo: Cuenta hacia abajo desde un número dado a cero |
|||
====while==== |
|||
<syntaxhighlight lang="curto"> |
|||
'''Compiler:''' [[GCC]] 4.1.2 |
|||
: cuenta-abajo ( n -- ) empezar dup rc . 1- dup 0< hasta soltar ; |
|||
int main (void) { |
|||
</syntaxhighlight> |
|||
int condition = 1; |
|||
while ( condition ) { |
|||
// Do something |
|||
// Don't forget to change the value of condition. |
|||
// If it remains nonzero, we'll have an infinite loop. |
|||
} |
|||
} |
|||
=== |
===EMPEZAR-DENUEVO=== |
||
<syntaxhighlight lang="curto"> |
|||
'''Compiler:''' [[GCC]] 4.1.2 |
|||
\ EMPEZAR sentencias iteradas DENUEVO |
|||
int main (void) { |
|||
</syntaxhighlight> |
|||
int condition = 1; |
|||
ejemplo: repetir entrada de usuario (solo funciona en cli, no en la interface gráfica) |
|||
do { |
|||
<syntaxhighlight lang="curto"> |
|||
// Do something |
|||
: porsiempre ( -- ) empezar tecla emitir denuevo ; |
|||
// Don't forget to change the value of condition. |
|||
</syntaxhighlight> |
|||
// If it remains nonzero, we'll have an infinite loop. |
|||
} while ( condition ); |
|||
===EMPEZAR-MIENTRAS-REPETIR=== |
|||
} |
|||
<syntaxhighlight lang="curto"> |
|||
\ EMPEZAR sentencias iteradas incondicionales condicional MIENTRAS sentencias iteradas condicionales repetir |
|||
</syntaxhighlight> |
|||
ejemplo: cuenta hacia abajo desde un número dado a uno |
|||
<syntaxhighlight> |
|||
: cuenta-abajo ( n -- ) empezar dup mientras rc dup . 1- repetir soltar ; |
|||
</syntaxhighlight> |
|||
=={{header|Dafny}}== |
|||
<syntaxhighlight lang="dafny"> |
|||
var i: int := 0; |
|||
while i < n |
|||
invariant 0 <= i <= n |
|||
decreases n - i |
|||
{ |
|||
i := i + 1; |
|||
} |
|||
assert i == n; |
|||
</syntaxhighlight> |
|||
=={{header|Dao}}== |
|||
===For=== |
|||
<syntaxhighlight lang="java"> |
|||
for( i=0; i<9; ++i) io.writeln( i ); |
|||
for( i = 0 : 8 ) io.writeln( i );</syntaxhighlight> |
|||
===For In=== |
|||
<syntaxhighlight lang="java"> |
|||
items = { 1, 2, 3 } |
|||
for( item in items ) io.writeln( item ) |
|||
</syntaxhighlight> |
|||
===While=== |
|||
<syntaxhighlight lang="java"> |
|||
i = 0 |
|||
while( i < 5 ) { i += 1 } |
|||
</syntaxhighlight> |
|||
===Do While=== |
|||
<syntaxhighlight lang="java"> |
|||
i = 0 |
|||
do { i += 1 } while( i < 9 ) |
|||
</syntaxhighlight> |
|||
=={{header|Déjà Vu}}== |
|||
===For=== |
|||
Déjà Vu has a for-loop protocol, so you can write your own iterators. The most commonly used iterators are <code>in</code> and <code>range</code>. The first iterates over a list, the second takes two arguments and goes from the first to the second, like a classic for-loop. |
|||
<syntaxhighlight lang="dejavu"> |
|||
for i range 1 3: |
|||
!print i # prints 1, 2 and 3 |
|||
</syntaxhighlight> |
|||
===While=== |
|||
<syntaxhighlight lang="dejavu"> |
|||
while true: |
|||
!print "This is the song that never ends..." |
|||
</syntaxhighlight> |
|||
===Repeat=== |
|||
<syntaxhighlight lang="dejavu"> |
|||
repeat 3: |
|||
!print "This sentence is printed three times." |
|||
</syntaxhighlight> |
|||
==[[Factor]]== |
|||
'''NOT COVERED IN LOOP PAGES''' |
|||
===Looping=== |
|||
Most looping is done with recursion. Tail recursion is properly optimized. |
|||
<syntaxhighlight lang="factor"> |
|||
: forever ( quot -- ) dup slip forever ; inline |
|||
[ "A hungry raptor stalks you..." print flush 2000 random sleep ] forever |
|||
</syntaxhighlight> |
|||
===Iteration=== |
|||
<syntaxhighlight lang="factor"> |
|||
Most indices are implicit or not present at all. |
|||
3 [ "pint" drink ] times |
|||
{ "high" "level" "language" } [ print ] each |
|||
high |
|||
level |
|||
language |
|||
10 [ sq ] map |
|||
{ 0 1 4 9 16 25 36 49 64 81 } |
|||
{ 1 2 3 } { 4 5 6 } [ * ] 2map . |
|||
{ 4 10 18 } |
|||
10 [ even? ] subset . |
|||
V{ 0 2 4 6 8 } |
|||
0 10 3 <range> >array . |
|||
{ 0 3 6 9 } |
|||
10 1 -2 <range> >array . |
|||
{ 10 8 6 4 2 } |
|||
2222 [ dup 0 > ] [ 2/ dup ] [ ] unfold nip . |
|||
{ 1111 555 277 138 69 34 17 8 4 2 1 0 }a |
|||
</syntaxhighlight> |
|||
Iterating with an index: |
|||
<syntaxhighlight lang="factor"> |
|||
: indexed-alphabet. ( -- ) |
|||
"abcdefghijklmnopqrstuvwxyz" |
|||
[ [ 1string ] [ number>string ] bi* ": " glue print ] each-index ; |
|||
</syntaxhighlight> |
|||
==[[Forth]]== |
==[[Forth]]== |
||
[[Category:Forth]] |
|||
===DO-LOOP=== |
===DO-LOOP=== |
||
<syntaxhighlight lang="forth"> |
|||
( limit start ) DO ( iterated statements ) LOOP |
|||
( limit start ) DO ( iterated statements ) LOOP |
|||
( limit start ) DO ( iterated statements ) ( increment ) +LOOP |
|||
LEAVE \ exits a DO loop |
|||
LEAVE \ exits a DO loop |
|||
UNLOOP EXIT \ cleans up loop counters from return stack before returning from the current word |
|||
</syntaxhighlight> |
|||
example: Two standard iterations |
example: Two standard iterations |
||
<syntaxhighlight lang="forth"> |
|||
10 0 DO I . LOOP \ Prints the numbers from 0 to 9 |
|||
10 0 DO I . LOOP \ Prints the numbers from 0 to 9 |
|||
10 0 DO I . 2 +LOOP \ Prints the even numbers from 0 to 8 |
|||
</syntaxhighlight> |
|||
===BEGIN-UNTIL=== |
===BEGIN-UNTIL=== |
||
<syntaxhighlight lang="forth"> |
|||
BEGIN ( iterated statements ) ( conditional ) UNTIL |
|||
BEGIN ( iterated statements ) ( conditional ) UNTIL |
|||
</syntaxhighlight> |
|||
example: Counts down from a given number to zero |
example: Counts down from a given number to zero |
||
<syntaxhighlight lang="forth"> |
|||
: COUNTDOWN ( n -- ) BEGIN DUP CR . 1- DUP 0< UNTIL DROP ; |
|||
: COUNTDOWN ( n -- ) BEGIN DUP CR . 1- DUP 0< UNTIL DROP ; |
|||
</syntaxhighlight> |
|||
===BEGIN-AGAIN=== |
|||
<syntaxhighlight lang="forth"> |
|||
BEGIN ( iterated statements ) AGAIN |
|||
</syntaxhighlight> |
|||
example: echo user's input |
|||
<syntaxhighlight lang="forth"> |
|||
: FOREVER ( -- ) BEGIN KEY EMIT AGAIN ; |
|||
</syntaxhighlight> |
|||
===BEGIN-WHILE-REPEAT=== |
===BEGIN-WHILE-REPEAT=== |
||
<syntaxhighlight lang="forth"> |
|||
BEGIN ( conditional ) WHILE ( iterated statements ) REPEAT |
|||
BEGIN ( unconditional iterated statements ) ( conditional ) WHILE ( conditional iterated statements ) REPEAT |
|||
example: counts down from a given number to one |
example: counts down from a given number to one |
||
: COUNTDOWN ( n -- ) BEGIN DUP WHILE CR DUP . 1- REPEAT DROP ; |
|||
</syntaxhighlight> |
|||
Additional WHILE clauses may be added to a loop, but each extra WHILE requires a matching THEN after the REPEAT. |
|||
===Mixed Structures=== |
|||
Because Forth's compiler is laid bare to the programmer, it is quite easy to both define your own looping structures or combine existing structures in interesting ways. The rules for such combining are somewhat involved, though discussions can be found in the gforth user's manual, among other places. These more complex looping constructs can make up for Forth's lack of a "break" word, and can allow expressing complex loops without resorting to boolean variables. A practical example is also found in the [[Binary search]] task. |
|||
A good example of a useful combination is this complex loop: |
|||
<syntaxhighlight lang="forth"> |
|||
BEGIN |
|||
( condition 1 ) |
|||
WHILE |
|||
( condition 2 ) |
|||
UNTIL |
|||
( condition 2 succeeded ) |
|||
ELSE |
|||
( condition 1 failed ) |
|||
THEN |
|||
</syntaxhighlight> |
|||
An example of using this idiom in practice might be this pseudo-Forth |
|||
<syntaxhighlight lang="forth"> |
|||
BEGIN |
|||
read-next-record |
|||
WHILE |
|||
found-record |
|||
UNTIL |
|||
process-record |
|||
ELSE |
|||
error" Ran out of records looking for the right one!" |
|||
THEN |
|||
</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
|||
<h3>[[While_loop|While..Wend]]</h3> |
|||
Executes a block of statements while a condition is met.<br> |
|||
<syntaxhighlight lang="vbnet">While [ condition ] |
|||
[ statement block ] |
|||
Wend</syntaxhighlight> |
|||
<h3>[[For_loop|For..Next]]</h3> |
|||
Executes a block of statements while an iterator is less than or greater than an expression.<br> |
|||
<syntaxhighlight lang="vbnet">For iterator [ As datatype ] = startvalue To endvalue [ Step stepvalue ] |
|||
[ statement block ] |
|||
Next [ iterator ] |
|||
</syntaxhighlight> |
|||
<h3>[[While_loop|Do..Loop]]</h3> |
|||
Executes a block of statements while or until a condition is met. |
|||
<syntaxhighlight lang="vbnet">Do [ { Until | While } condition ] |
|||
[ statement block ] |
|||
Loop</syntaxhighlight> |
|||
or |
|||
<syntaxhighlight lang="vbnet">Do |
|||
[ statement block ] |
|||
Loop [ { Until | While } condition ] |
|||
</syntaxhighlight> |
|||
<h3>Intra-loop control</h3> |
|||
Continue While, Continue For and Continue Do |
|||
Prematurely re-enters a loop.<br> |
|||
<syntaxhighlight lang="vbnet">Continue {Do | For | While}</syntaxhighlight> |
|||
Exit While, Exit For and Exit Do |
|||
Prematurely breaks out of a loop. |
|||
<syntaxhighlight lang="vbnet">Exit {Do | For | While | Select }</syntaxhighlight> |
|||
<syntaxhighlight lang="vbnet">Exit {Sub | Function | Operator | Constructor | Destructor | Property }</syntaxhighlight> |
|||
<syntaxhighlight lang="vbnet">Exit {Do [, Do [ , ...] ] | |
|||
For [, For [ , ...] ] | |
|||
While [, While, [...] ] | |
|||
Select [, Select [ , ...] ] }</syntaxhighlight> |
|||
=={{header|Frink}}== |
|||
In all of the loops below, the curly braces can be omitted if the body is a single statement. |
|||
===For Loop=== |
|||
A <CODE>for</CODE> loop is really a <CODE>foreach</CODE> loop that can work with range operators or iterate through various data structures. The <CODE>to</CODE> operator creates an enumerating expression that lazily steps through its range. |
|||
<syntaxhighlight lang="frink"> |
|||
for i = 1 to 1000000 |
|||
{ |
|||
println[i] |
|||
} |
|||
</syntaxhighlight> |
|||
The <CODE>to</CODE> operator can be combined with a <CODE>step</CODE> statement: |
|||
<syntaxhighlight lang="frink"> |
|||
for i = 1 to 1000000 step 3 |
|||
println[i] |
|||
</syntaxhighlight> |
|||
As a <CODE>foreach</CODE> statement. The <CODE>for</CODE> construct can iterate over the elements of an array, set, dictionary, or enumerating expression. |
|||
<syntaxhighlight lang="frink"> |
|||
for i = [2,3,7,9] |
|||
println[i] |
|||
</syntaxhighlight> |
|||
===Do...While Loop=== |
|||
<syntaxhighlight lang="frink"> |
|||
i=0 |
|||
do |
|||
{ |
|||
i = i+1 |
|||
} while i<1000 |
|||
</syntaxhighlight> |
|||
==[[Groovy]]== |
|||
===While Loops=== |
|||
while (true) { |
|||
println 'groovy' |
|||
} |
|||
===For Loops=== |
|||
<pre> |
|||
// iterate over a range |
|||
x = 0 |
|||
for (i in 1..3) { x += i } |
|||
assert x == 6 |
|||
// iterate over a list |
|||
x = 0 |
|||
for (i in [1, 2, 3]) { x += i } |
|||
assert x == 6 |
|||
// iterate over an array |
|||
x = 0 |
|||
for (i in (1..3).toArray()) { x += i } |
|||
assert x == 6 |
|||
// iterate over a map's key/value pairs |
|||
x = 0 |
|||
for (i in map) { x += i.value } |
|||
assert x = 6 |
|||
// iterate over a map's values |
|||
x = 0 |
|||
for (i in map.values()) { x += i } |
|||
assert x == 6 |
|||
// iterate over the characters in a string |
|||
text = 'abc' |
|||
list = [] |
|||
for (c in text) { list.add(c) } |
|||
assert list == ['a', 'b', 'c'] |
|||
</pre> |
|||
===Each=== |
|||
<pre> |
|||
def stringList = [ "java", "perl", "python", "ruby" ]; |
|||
def stringMap = [ "Su" : "Sunday", "Mo" : "Monday", "Tu" : "Tuesday", |
|||
"We" : "Wednesday", "Th" : "Thursday", "Fr" : "Friday", |
|||
"Sa" : "Saturday" ]; |
|||
stringList.each() { print " ${it}" }; println ""; |
|||
// java perl python ruby |
|||
stringMap.each() { key, value -> println "${key} == ${value}" }; |
|||
// Su == Sunday |
|||
// We == Wednesday |
|||
// Mo == Monday |
|||
// Sa == Saturday |
|||
// Th == Thursday |
|||
// Tu == Tuesday |
|||
// Fr == Friday |
|||
stringList.eachWithIndex() { obj, i -> println " ${i}: ${obj}" }; |
|||
// 0: java |
|||
// 1: perl |
|||
// 2: python |
|||
// 3: ruby |
|||
stringMap.eachWithIndex() { obj, i -> println " ${i}: ${obj}" }; |
|||
// 0: Su=Sunday |
|||
// 1: We=Wednesday |
|||
// 2: Mo=Monday |
|||
// 3: Sa=Saturday |
|||
// 4: Th=Thursday |
|||
// 5: Tu=Tuesday |
|||
// 6: Fr=Friday |
|||
</pre> |
|||
==[[Haskell]]== |
|||
Most of the usual applications for loops are realized in Haskell by operations on (lazy) lists, like '''map''', '''fold''' or '''filter'''. It's unusual to use loops in an imperative style. However, if one insists on it, it's easy to make your own implementation of any loop variant. |
|||
Here are a few examples: |
|||
===Pre-checked loop (while)=== |
|||
whileM :: Monad m => m Bool -> m a -> m () |
|||
whileM cond body = |
|||
cond >>= \b -> if b then body >> untilM cond body else return () |
|||
===Post-checked loop (repeat-until)=== |
|||
untilM :: Monad m => m Bool -> m a -> m () |
|||
untilM cond body = |
|||
body >> cond >>= \b -> if b then return () else untilM cond body |
|||
===For-style loop=== |
|||
Simplest done by iterating over a list: |
|||
forM :: Monad m => [a] -> (a -> m ()) -> m () |
|||
forM [] f = return () |
|||
forM (x:xs) f = f x >> forM xs f |
|||
==[[IDL]]== |
==[[IDL]]== |
||
[[Category:IDL]] |
|||
It should be noted that IDL programmers tend to avoid loops -- most of the time loops are used to access the elements of arrays or vectors, and since IDL is an array language the same purpose can almost always be served in a faster, more elegant and more readable way though any of the array operations. |
It should be noted that IDL programmers tend to avoid loops -- most of the time loops are used to access the elements of arrays or vectors, and since IDL is an array language the same purpose can almost always be served in a faster, more elegant and more readable way though any of the array operations. |
||
Line 291: | Line 605: | ||
The <tt>break</tt> statement will immediately terminate the current innermost <tt>for</tt>, <tt>while</tt>, <tt>repeat</tt>, <tt>if</tt>, <tt>case</tt> or <tt>switch</tt> without having to resort to a <tt>goto</tt>. |
The <tt>break</tt> statement will immediately terminate the current innermost <tt>for</tt>, <tt>while</tt>, <tt>repeat</tt>, <tt>if</tt>, <tt>case</tt> or <tt>switch</tt> without having to resort to a <tt>goto</tt>. |
||
==[[ |
==[[Jinja]]== |
||
[[Category:Java]] |
|||
===while=== |
|||
while(true) |
|||
{ |
|||
foo(); |
|||
} |
|||
===do-while=== |
|||
do |
|||
{ |
|||
foo(); |
|||
} |
|||
while (true) |
|||
===for=== |
===for=== |
||
<lang jinja> |
|||
print(Template("""{% for lang in ["Jinja", "Python", "Swift", "Nim"] %} |
|||
{{ loop.index }}) {{ lang }} |
|||
{%- endfor %}""").render()) |
|||
</lang> |
|||
==[[Kabap]]== |
|||
for(int i = 0; i < 5; i++) |
|||
{ |
|||
foo(); |
|||
} |
|||
There is no native loop command in Kabap, but labels, variables, jumps and conditional execution are supported which is enough to create a basic loop structure. Support for native loops is being prepared for the next major release. |
|||
===foreach=== |
|||
'''Platform:''' [[J2SE]] 1.5.0 |
|||
===Basic loop=== |
|||
Object[] objects; |
|||
<lang Kabap> |
|||
// ... |
|||
$i = 0; |
|||
for (Object current : objects[]) { |
|||
:start; |
|||
// ... |
|||
// Your loop code here |
|||
} |
|||
$i = $i + 1; |
|||
if $i < 20; |
|||
goto start; |
|||
</lang> |
|||
==[[Logo]]== |
|||
int[] numbers; |
|||
forever [right random 360 forward 10] |
|||
// ... |
|||
for (int i : numbers) { |
|||
// ... |
|||
} |
|||
repeat 5 [right 180-36 forward 100] |
|||
==[[JavaScript]]== |
|||
[[Category:JavaScript]] |
|||
===while=== |
|||
Repeat and forever also have access to a loop counter, starting at 1. |
|||
while(true) { |
|||
repeat 10 [print repcount] |
|||
foo(); |
|||
} |
|||
while [:x > 0] [make "x :x / 2] |
|||
===do while=== |
|||
do.while [make "x :x / 2] [:x > 0] |
|||
until [:x = 0] [make "x :x / 2] |
|||
do { |
|||
do.until [make "x :x / 2] [:x = 0] |
|||
} while(test); |
|||
===for=== |
|||
==[[LSE64]]== |
|||
for(var i = 0; i < 5; i++) { |
|||
LSE's loop words all work via tail recursion, like [[Scheme]], by re-executing the current word. If used interactively, "repeat" works upon the current line. Exiting words, like "&&", "||", and "exit" can be used to exit an otherwise infinite loop (see other tasks). |
|||
foo(); |
|||
infinite : " again and " ,t repeat |
|||
} |
|||
limited : continue? &repeat |
|||
Counted loops execute a specified word ''n'' times. Within that word, "count" accesses a loop counter, counted down to zero. |
|||
===for in=== |
|||
body : count , sp |
|||
10 body iterate # 10 9 8 7 6 5 4 3 2 1 |
|||
body? : count , sp count 5 > |
|||
10 body? &iterate # 10 9 8 7 6 5 |
|||
==[[Make]]== |
|||
//iterate through property names of an object |
|||
Make does looping through recursion. |
|||
SUCC=`expr $* + 1` |
|||
MAX=10 |
|||
all: 0-n; |
|||
%-n: %-echo |
|||
var obj = {prop1:"a", prop2:"b", prop3:"c"}; |
|||
@-make -f loop.mk $(SUCC)-n MAX=$(MAX) |
|||
for (var key in obj) |
|||
alert( key + ' is set to ' + obj[key] ); |
|||
%-echo: |
|||
@echo $* |
|||
$(MAX)-n: $(MAX)-echo; |
|||
Invoking it |
|||
=== for each in=== |
|||
|make -f loop.mk MAX=2 |
|||
0 |
|||
//iterate through property values of an object |
|||
1 |
|||
2 |
|||
var obj = {prop1:"a", prop2:"b", prop3:"c"}; |
|||
for each(var element in obj) |
|||
alert( element ); |
|||
==[[newLISP]]== |
==[[newLISP]]== |
||
{{works with|newLISP|v.9.0}} |
|||
===dotimes=== |
===dotimes=== |
||
'''Interpreter:''' [[newLISP]] v.9.0 |
|||
(dotimes (x 10) (println (+ x 1))) |
(dotimes (x 10) (println (+ x 1))) |
||
===do-until=== |
===do-until=== |
||
'''Interpreter:''' [[newLISP]] v.9.0 |
|||
(set 'x 1) |
(set 'x 1) |
||
Line 383: | Line 687: | ||
===do-while=== |
===do-while=== |
||
'''Interpreter:''' [[newLISP]] v.9.0 |
|||
(set 'x 1) |
(set 'x 1) |
||
Line 390: | Line 692: | ||
===for=== |
===for=== |
||
(for (x 1 10) (println x)) |
|||
==[[OCaml]]== |
|||
===let rec=== |
|||
The for and while loops are imperative features of OCaml, and most often it is rather recommended to prefer using functional loop designed with recursive functions, or better when iterating over a list or an array using a built-in iterator from the standard library or the extLib library. |
|||
<lang ocaml>let rec loop i = |
|||
Printf.printf "%d\n" i; |
|||
if i <= 4 then loop (i + 1) |
|||
in |
|||
loop 0</lang> |
|||
===Built-in Iterators=== |
|||
'''Interpreter:''' [[newLISP]] v.9.0 |
|||
<lang ocaml>List.iter |
|||
List.fold_left |
|||
Array.iter |
|||
Array.iteri</lang> |
|||
=={{header|Prolog}}== |
|||
(for (x 1 10) (println x)) |
|||
There are three primitive methods of looping in Prolog: recursion, fail-driven loops, and repeat-driven loops. |
|||
<lang Prolog>% recursion as loop |
|||
==[[Pascal]]== |
|||
print_each_element([]). |
|||
[[Category:Pascal]] |
|||
print_each_element([E|T]) :- writeln(E), print_each_element(T). |
|||
% fail-driven loop |
|||
===while=== |
|||
fact(foo). |
|||
fact(bar). |
|||
fact(baz). |
|||
print_each_fact :- |
|||
( fact(X), writeln(X), fail |
|||
; true ). |
|||
% equivalently |
|||
'''Compiler:''' [[Turbo Pascal]] 7.0 |
|||
%print_each_fact :- fact(X), writeln(X), fail. |
|||
%print_each_fact. |
|||
% repeat-driven loop |
|||
WHILE condition1 DO |
|||
print_each_fact_again :- |
|||
BEGIN |
|||
repeat, |
|||
fact(X), |
|||
writeln(X), |
|||
X = baz, |
|||
!. |
|||
go :- |
|||
===repeat-until=== |
|||
print_each_element([foo, bar, baz]), |
|||
print_each_fact, |
|||
print_each_fact_again.</lang> |
|||
Of the three recursion is the favoured approach as it requires no non-logical predicates and is thus easy to read in its declarative form. |
|||
'''Compiler:''' [[Turbo Pascal]] 7.0 |
|||
REPEAT |
|||
procedure1; |
|||
procedure2; |
|||
UNTIL condition1; |
|||
The fail-driven loop form is a(n ab)use of the built-in backtracking mechanism of Prolog's reasoning engine. In the specific example provided, fact(X) will first succeed, binding "foo" to X. It will then write "foo" to the output (as a side effect of the writeln/1 predicate). It then hits the call to fail/0 which is a non-logical predicate which always fails and thus always triggers backtracking. On backtracking, the runtime will try fact(X) again and will find that it is true when X is bound to "bar". This will then print and backtrack again. A third time binds to and prints "baz". A fourth time will fail because there is no more solution to the goal "fact(X)". This triggers a further backtrack and a try on the second branch of the disjunction. That second branch invokes the true/0 predicate which always succeeds. This exits the query with an overall success. |
|||
===for=== |
|||
The repeat-driven loop uses similar (ab)use of the backtracking mechanism. Instead of employing a predicate that always fails, however, it employs one that will always succeed: repeat/0. Thus, in this sample, fact(X) works as before, as does writeln(X), but the attempt to unify X with "baz" will fail for the first two attempts, causing the system to backtrack until it hits repeat. Since repeat always succeeds it drives the engine forward again, testing each fact in succession. Once X is unified with "baz" (which is to say once X contains the value "baz") the predicate carries on. The cut operator !/0, guarantees that the predicate won't be re-entered later. |
|||
'''Compiler:''' [[Turbo Pascal]] 7.0 |
|||
As with any language permitting higher-order invocations, using the looping primitives directly as above is often not a desirable thing. Instead higher-order features would be used. |
|||
FOR counter=1 TO 10 DO |
|||
BEGIN |
|||
procedure1; |
|||
procedure2; |
|||
END; |
|||
<lang Prolog>% using maplist/2 to replace explicit recursion on a list |
|||
==[[Perl]]== |
|||
print_each_element(L) :- maplist(writeln, L). |
|||
[[Category:Perl]] |
|||
% using forall/2 to replace an explicit fail-driven loop |
|||
===while=== |
|||
fact(foo). |
|||
fact(bar). |
|||
fact(baz). |
|||
print_each_fact() :- forall(fact(X), writeln(X)).</lang> |
|||
There are a myriad of such predicates available in a useful Prolog implementation (SWI-Prolog provides, non-exhaustively: include/3, exclude/3, partition/4-5, maplist/2-5, foldl/4-7, scanl/4-6, aggregate/3-4, aggregate_all/3-4, forall/2, findall/3-4, findnsols/4-5, bagof/3, setof/3, … just as the more fundamental wrappings.) If the provided predicates do not permit the kinds of functionality desired for common patterns, it is trivial to make a new one. As an illustration, this is the source code for forall/2: |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my $condition1 = 0; |
|||
while ( $condition1 ) { |
|||
# Do something. |
|||
# Remember to change the value of condition1 at some point. |
|||
} |
|||
<lang Prolog>:- meta_predicate forall(0,0). |
|||
===do-while=== |
|||
forall(A, B) :- \+ (call(A), \+ call(B)).</lang> |
|||
=={{header|Pop11}}== |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my $condition1 = 0; |
|||
do { |
|||
# Do something. |
|||
# Remember to change the value of condition1 at some point. |
|||
} while ( $condition1 ); |
|||
===until=== |
|||
=== until === |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
Variant of while is until loop: |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my $condition1 = 1; |
|||
until ( $condition1 ) { |
|||
# Do something. |
|||
# Remember to change the value of condition1 at some point. |
|||
} |
|||
until condition do /* Action */ enduntil; |
|||
is equivalent to: |
|||
===do-until=== |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
while not(condition) do /* Action */ endwhile; |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my $condition1 = 1; |
|||
do { |
|||
# Do something. |
|||
# Remember to change the value of condition1 at some point. |
|||
} until ( $condition1 ); |
|||
===for=== |
=== for === |
||
One can process all elements of a list: |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
for x in [a b c] do x => endfor; |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my $limit = 5; |
|||
for ( my $iterator = 0; $iterator < $limit; $iterator++ ) { |
|||
# Do something |
|||
} |
|||
# for-variant, implicit iteration |
|||
for (0..$limit) { |
|||
# Do something |
|||
} |
|||
do_something() for 0..$limit; |
|||
It is possible to simultaneously process multiple lists: |
|||
===foreach=== |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
for x y in [a b c], [1 2 3] do [^x ^y] => endfor; |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my @numbers = (1, 2, 3); |
|||
my %names = (first => "George", last => "Jetson"); |
|||
foreach my $number (@numbers) { |
|||
# Do something with $number |
|||
} |
|||
foreach my $key (keys %names) { |
|||
# Do something with $key (values are accessible as %names{$key} ) |
|||
} |
|||
in first iteration sets x to "a" and y to 1, in the second x is "b" and y is 2, in the third (last) iteration x is "c" and y is 3. The iteration ends when the shortest list is exhausted. |
|||
===map=== |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
Sometimes one wants to process tails of the list, to do this use on keyword instead of in keyword: |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my @numbers = (1, 2, 3); |
|||
my @target; |
|||
@target = map { |
|||
# Do something with $_ |
|||
} @numbers; |
|||
@target = map($_ + 1, @numbers); |
|||
sub a_sub { |
|||
# Do something with $_ |
|||
} |
|||
@target = map a_sub @numbers; |
|||
for x on [a b c] do x => endfor; |
|||
===grep=== |
|||
'''Interpreter:''' [[Perl]] 5.8.8 |
|||
in first iteration sets x to [a b c], in the second to [b c], etc... |
|||
#!/usr/bin/perl -w |
|||
use strict; |
|||
my @people = qw/Bobbie Charlie Susan/; |
|||
my @target; |
|||
@target = grep { |
|||
# Discriminate based on $_ |
|||
} @people; |
|||
# Feed grep into map, this picks out elements 1, 3, 5, etc. |
|||
@target = map($people[$_], grep($_ & 1, 0..$#people)); |
|||
# Pick out the diminutive names |
|||
@target = grep(/ie$/, @people); |
|||
sub a_sub { |
|||
# Do something with $_, and return a true or false value |
|||
} |
|||
@target = grep a_sub @people; |
|||
There is also "counting" version of for loop: |
|||
==[[PHP]]== |
|||
[[Category:PHP]] |
|||
for x from 2 by 2 to 7 do x => endfor; |
|||
===while=== |
|||
goes trough 2, 4 and 6. Ommited by frase means by 1. |
|||
while(ok()) { |
|||
foo(); |
|||
bar(); |
|||
baz(); |
|||
} |
|||
There is alse a C-like for loop: |
|||
===do-while=== |
|||
for action1 step action2 till condition do /* Actions */ endfor; |
|||
$i = 0; |
|||
do { |
|||
echo $i; |
|||
} while ($i > 0); |
|||
===for=== |
|||
is equivalent to |
|||
for($i = 0; $i < 10; ++$i) { |
|||
echo $i; |
|||
} |
|||
action1 |
|||
===foreach=== |
|||
while not(condition) do |
|||
/* Actions */ |
|||
action2 |
|||
endwhile; |
|||
There are more specialized kinds of loops, but we skip them here. |
|||
foreach(range(0, 9) as $i) { |
|||
echo $i; |
|||
} |
|||
=== quitloop quitif quitunless === |
|||
foreach is only used for arrays, which is not obvious from the above example |
|||
Inside loops one can use control transfers to prematurely exit the loop or end current iteration and start the next one: |
|||
while true do n - 1 -> n; quitif(n=0); endwhile; |
|||
foreach($array as $key => $value) { |
|||
echo $key.' is '.$value; |
|||
quits loop when n=0. quitloop unconditionally quits loop, |
|||
} |
|||
quitunless(x) is equivalent to quitif(not(x)). |
|||
=== nextloop nextif nextunless === |
|||
Similarely to quitloop nextloop unconditionally ends current iteration and starts the new one, nextif(x) ends current iteration when x is true, nextunless(x) is equivalent to nextif(not(x)). The loop control transfers can be also used inside for (and until) loops. |
|||
Finally, it is frequently possible to avoid explicit iteration using higher order map functions (like appdata and mapdata). |
|||
==[[PostScript]]== |
==[[PostScript]]== |
||
[[Category:PostScript]] |
|||
The "<tt>for</tt>" operator expects three numbers and a procedure on the stack. It will consume all four arguments then it will push the first number on the stack, execute the procedure, increase the first number by the second number, push it on the stack, execute the procedure etc until the third number is reached. For example |
The "<tt>for</tt>" operator expects three numbers and a procedure on the stack. It will consume all four arguments then it will push the first number on the stack, execute the procedure, increase the first number by the second number, push it on the stack, execute the procedure etc until the third number is reached. For example |
||
Line 623: | Line 836: | ||
==[[Python]]== |
==[[Python]]== |
||
[[Category:Python]] |
|||
=== |
===for=== |
||
Frequently one wants to both iterate over a list and increment a counter: |
|||
<lang python> |
|||
'''Interpreter''': Python 2.5 |
|||
mylist = ["foo", "bar", "baz"] |
|||
for i, x in enumerate(mylist): |
|||
print "Element no.", i, " is", x |
|||
</lang> |
|||
foo could for example open a file or create a lock or a database transaction: |
|||
Iterating over more than one list + incrementing a counter: |
|||
with foo() as bar: |
|||
baz(bar) |
|||
<lang python> |
|||
for counter, [x, y, z] in enumerate(zip(lst1, lst2, lst3)): |
|||
print counter, x, y, z |
|||
</lang> |
|||
=== list comprehension expressions === |
|||
Typically used when you want to create a list and there is little logic involved. Faster than for loop: |
|||
positives = [n for n in numbers if n > 0] |
|||
A list comprehension is an expression rather than a statement. This allows them to be used as arguments to a function: |
|||
<lang python> |
|||
def square_each(n): |
|||
results = [] |
|||
for each in n: |
|||
results.append(each * each) |
|||
return results |
|||
squares_3x5 = square_each([x for x in range(100) if (x%3)==0 and (x%5)==0]) |
|||
# Return a list of all the squares of numbers from 1 up to 100 those numbers are |
|||
# multiples of both 3 and 5. |
|||
</lang> |
|||
===while=== |
===while=== |
||
Typical use: |
|||
while ok(): |
|||
foo() |
|||
bar() |
|||
baz() |
|||
else: |
|||
# break was not called |
|||
quux() |
|||
<lang python> |
|||
===for=== |
|||
while True: |
|||
# Do stuff... |
|||
if condition: |
|||
break |
|||
</lang> |
|||
You can add optional ''else'', which is executed only if the expression tested was false. Typically used for searches. |
|||
for i in range(10): |
|||
print i |
|||
<lang python> |
|||
while True: |
|||
# Do stuff... |
|||
if found: |
|||
results = ... |
|||
break |
|||
else: |
else: |
||
print 'Not found' |
|||
# break was not called |
|||
</lang> |
|||
foo() |
|||
Since Python has no "bottom-tested" loop construct (such as "do ... until") ... it's common Python practice to either rethink the design in terms of iteration or to use an ''while 1'' (infinite loop) and ''break'' out of it as appropriate. |
|||
for x in ["foo", "bar", "baz"]: |
|||
print x |
|||
==[[Raven]]== |
|||
''Does range(10) return an array? The above two examples may be redundant.'' |
|||
===each=== |
|||
10 each as i # counted loop |
|||
"index is %(i)d\n" print |
|||
'hello world' each as c # string characters |
|||
"%(c)c" print |
|||
[ 'a' 'b' 'c' ] each as item # list items |
|||
"%(item)s" print |
|||
{ 'a' 1 'b' 2 } each pair as k, v # hash key/val pairs |
|||
"%(k)s => %(v)d\n" print |
|||
'SELECT * FROM table' mysql query each as row # iterable resource |
|||
row print |
|||
===repeat while/until=== |
|||
repeat <some_condition> while |
|||
<some_process> |
|||
repeat <come_condition> until |
|||
<some_process> |
|||
=={{header|REXX}}== |
|||
===repeat=== |
|||
This example shows how to perform a loop for one million times. |
|||
<lang rexx>n= 1000000 |
|||
x= 1 |
|||
y= 12 |
|||
z= 0 |
|||
do n |
|||
z=someFunction(z, x, y) |
|||
end /*n*/</lang> <br><br> |
|||
==[[ |
==[[Seed7]]== |
||
In Seed7 new statements can be declared easily. This feature is not explained here. Here are examples of the predefined loops: |
|||
[[Category:Ruby]] |
|||
===while=== |
===while=== |
||
while |
while TRUE do |
||
foo |
foo; |
||
end |
end while; |
||
===repeat=== |
|||
repeat |
|||
foo; |
|||
until FALSE; |
|||
===for=== |
===for=== |
||
for i |
for i range 0 to 4 do |
||
foo |
foo; |
||
end |
end for; |
||
for i range 4 downto 0 do |
|||
=== each === |
|||
foo; |
|||
end for; |
|||
[ |
for stri range []("foo", "bar", "baz") do |
||
writeln(stri); |
|||
puts x |
|||
end |
end for; |
||
== |
==SETL4== |
||
<lang setl4> |
|||
define('prime(n)set.this') :(prime.end) |
|||
* Tests if _n_ is a prime integer. |
|||
array = ['foo', 'bar', 'baz'].collect do |x| |
|||
foo x |
|||
end |
|||
prime |
|||
=== map === |
|||
n = integer(n) +n |
|||
array = ['foo', 'bar', 'baz'].map {|x| foo x } |
|||
eq(n,2) :s(return) |
|||
even(n) :s(freturn) |
|||
exists(new('iter 3 ' square.root(n) ' 2'), 'multiple(n,this)') :s(freturn)f(return) |
|||
prime.end |
|||
=== inject === |
|||
define('primes(n)set.this') :(primes.end) |
|||
string = ['foo', 'bar', 'baz'].inject("") do |s,x| |
|||
s << x |
|||
end |
|||
* Returns set of primes less than _n_. |
|||
sum = ['foo', 'bar', 'baz'].inject(0) do |s,x| |
|||
s + x.size |
|||
end |
|||
primes |
|||
product = ['foo', 'bar', 'baz'].inject(1) do |p,x| |
|||
p * x.size |
|||
end |
|||
primes = filter(new('iter 2 ' (n - 1)),'prime(this)') :(return) |
|||
boolean = ['foo', 'bar', 'baz'].inject(true) do |b,x| |
|||
primes = new('set') |
|||
iter = new('iter 2 ' (n - 1)) |
|||
end |
|||
loop(iter) |
|||
primes.loop |
|||
==[[Smalltalk]]== |
|||
[[Category:Smalltalk]] |
|||
this = next(iter) :f(return) |
|||
===whileTrue/whileFalse=== |
|||
prime(this) add(primes,this) :(primes.loop) |
|||
primes.end |
|||
x := 0. |
|||
</lang> |
|||
[ x < 100 ] |
|||
whileTrue: [ x := x + 10.]. |
|||
==[[SIMPOL]]== |
|||
[ x = 0 ] |
|||
In [[SIMPOL]] there is only one looping construct. It is very flexible and can be used as a while, a repeat, or a combination of both. |
|||
whileFalse: [ x := x - 20.]. |
|||
== |
===while=== |
||
[[Category:Tcl]] |
|||
=== foreach === |
|||
foreach i {foo bar baz} { |
|||
puts "$i" |
|||
} |
|||
Note that <tt>foreach</tt> also accepts multiple variables: |
|||
foreach {x y} {1 2 3 4} { |
|||
puts "$x,$y" |
|||
} |
|||
And also multiple lists: |
|||
foreach i {1 2 3} j {a b c} { |
|||
puts "$i,$j" |
|||
} |
|||
Or any combination of variables/list: |
|||
foreach i {1 2 3} {x y} {a b c d e f} { |
|||
puts "$i,$x,$y" |
|||
} |
|||
<lang simpol>while [condition] |
|||
=== for === |
|||
// Actions taken here |
|||
for {set i 0} {$i < 10} {incr i} { |
|||
end while [condition]</lang> |
|||
puts $i |
|||
} |
|||
Either condition or both can be present. Not setting either condition will result in an endless loop. The first condition will continue the loop if the result is true, the second will exit the loop if it is true. In [[SIMPOL]] code it is common to see both present, with the initial condition being the standard method of exiting the loop, and the end while condition used for exiting because of an error. |
|||
It bears noting that the three parts of the for loop do not have to consist of "initialize variable", "test value of variable" and "increment variable". This is a common way to think of it as it resembles the "for" loop in other languages, but many other things make sense. For example this for-loop will read a file line-by-line: |
|||
In this abbreviated example, the code will read records from a database table in a loop, placing each in record object in an array element, until it reaches the end of the table. |
|||
set line "" |
|||
for { set io [open test.txt r] } { ![eof $io] } { gets $io line } { |
|||
if { $line != "" } { ...do something here... } |
|||
} |
|||
<lang simpol>function readrecs(sbme1table table) |
|||
(This is a somewhat awkward example; just to show what is possible) |
|||
sbme1record r |
|||
array recs |
|||
integer e, i |
|||
e = 0 |
|||
i = 0 |
|||
recs =@ array.new() |
|||
while {$i < 10} { |
|||
r =@ table.select(error=e) |
|||
puts [incr i] |
|||
while r !@= .nul |
|||
} |
|||
i = i + 1 |
|||
recs[i] =@ r |
|||
r =@ r.select(error=e) |
|||
end while e != 0 |
|||
end function recs</lang> |
|||
The final condition should best be read as: "end the while, if this is true". |
|||
==[[UNIX Shell]]== |
|||
[[Category:UNIX Shell]] |
|||
===for=== |
|||
'''Interpreter:''' [[Bourne Again SHell]] |
|||
Another typical use of the loop is the traversing of rings that are commonly used in [[SIMPOL]]. |
|||
#!/bin/bash |
|||
ARRAY="VALUE1 VALUE2 VALUE3 VALUE4 VALUE5" |
|||
for ELEMENT in $ARRAY |
|||
do |
|||
echo $ELEMENT # Print $ELEMENT |
|||
done |
|||
<lang simpol>function getfieldnames(sbme1table table) |
|||
'''Interpreter:''' [[Debian Almquist SHell]] |
|||
sbme1field field |
|||
integer i |
|||
array fieldnames |
|||
fieldnames =@ array.new() |
|||
#!/bin/sh |
|||
i = 0 |
|||
ARRAY="VALUE1 VALUE2 VALUE3 VALUE4 VALUE5" |
|||
field =@ table.firstfield |
|||
while field !@= .nul |
|||
for ELEMENT in $ARRAY |
|||
i = i + 1 |
|||
do |
|||
fieldnames[i] = field.name |
|||
echo $ELEMENT # Print $ELEMENT |
|||
field =@ field.next |
|||
done |
|||
end while field =@= table.firstfield |
|||
end function fieldnames</lang> |
|||
== |
=={{header|Sing}}== |
||
<lang Sing>fn loops() void |
|||
'''Interpreter:''' [[Bourne Again SHell]] |
|||
{ |
|||
// while: the condition must be strictly of boolean type |
|||
var idx = 0; |
|||
while (idx < 10) { |
|||
++idx; |
|||
} |
|||
// for in an integer range, the last value is excluded |
|||
// it is local to the loop and must not be previously declared |
|||
for (it in 0 : 10) { |
|||
} |
|||
// reverse direction |
|||
for (it in 10 : 0) { |
|||
} |
|||
// configurable step. The loop stops when it >= the final value |
|||
for (it in 0 : 100 step 3) { |
|||
} |
|||
// with an auxiliary counter. The counter start always at 0 and increments by one at each iteration |
|||
for (counter, it in 3450 : 100 step -22) { |
|||
} |
|||
// value assumes in turn all the values from array |
|||
var array [*]i32 = {0, 10, 100, 1000}; |
|||
for (value in array) { |
|||
} |
|||
// as before with auxiliary counter |
|||
for (counter, value in array) { |
|||
} |
|||
}</lang> |
|||
==[[SNUSP]]== |
|||
==in==!/==body==?\==out== |
|||
\==ydob===/ |
|||
The basic loop structure can be modified in many ways. You can have a pre-loop test by including '''?''' before the loop. |
|||
A unique feature of SNUSP is the ability to write ''bi-directional'' loops, designed for different effect depending on which direction the flow of control is running around the loop. The two entry points into this subroutine will move a value either up or down one cell, determined by the direction the loop is circulating. |
|||
# # |
|||
up1====?!/->+<\ |
|||
? ? |
|||
down1==?!\<+>-/ |
|||
# # |
|||
==[[Sparkling]]== |
|||
While loop (test-first loop): |
|||
<lang sparkling>var n = -1; |
|||
print("Enter 0 to exit"); |
|||
while n != 0 { |
|||
n = toint(getline()); |
|||
print(n); |
|||
}</lang> |
|||
For loop (alternate form of test-first loop, idiomatic approach to counting): |
|||
<lang sparkling>var i; |
|||
for i = 0; i < 10; i++ { |
|||
print(i); |
|||
}</lang> |
|||
Do-while loop (test-last loop): |
|||
<lang sparkling>print("enter empty line to exit"); |
|||
var s; |
|||
do { |
|||
s = getline(); |
|||
print(s); |
|||
} while s != "";</lang> |
|||
==[[Toka]]== |
|||
=== countedLoop === |
|||
Counts up or down until the boundaries are met. |
|||
10 0 [ i . ] countedLoop |
|||
0 10 [ i . ] countedLoop |
|||
=== whileTrue === |
|||
Repeatedly executes a quote until the quote returns true. |
|||
100 [ dup . 1 - dup 0 <> ] whileTrue |
|||
=== whileFalse === |
|||
Repeatedly executes a quote until the quote returns true. |
|||
0 [ dup . 1 + dup 101 = ] whileFalse |
|||
==[[Tern]]== |
|||
Tern has several distinct loop statements. |
|||
===Infinite Loop=== |
|||
<lang tern>let v = 0; |
|||
loop { |
|||
println(v++); |
|||
}</lang> |
|||
===While Loop=== |
|||
<lang tern>let v = 0; |
|||
while(v < 100) { |
|||
println(v++); |
|||
}</lang> |
|||
===For Loop=== |
|||
<lang tern>for(let v = 0; v < 100; v++) { |
|||
println(v); |
|||
}</lang> |
|||
===For In Loop=== |
|||
<lang tern>for(v in 0 to 99) { |
|||
println(v); |
|||
}</lang> |
|||
=={{header|Woma}}== |
|||
Woma is limited to for loops. |
|||
==Infinte Loop== |
|||
<lang woma>i<@>iter(int, 1) |
|||
print(i) |
|||
</lang> |
|||
===For Loop=== |
|||
<lang woma>i<@>range(100) |
|||
#!/bin/bash |
|||
print(i) |
|||
while true |
|||
</lang> |
|||
do |
|||
... |
|||
done |
Latest revision as of 13:31, 3 October 2023
In this former task, we document loop structures offered by different languages.
- What are loops?
Loops are control structures that allow sections of code to be executed repeatedly according to the controlling conditions of the loop.
There are two types of loops:
- Repetition
Additionally, there is the overly simple repetitive loop: repetition. The simplistic construct executes a block of code, or a procedure, a given number of times, without explicitly exposing any state change to the looped procedure.
- Iterative loops
An iterative loop repeatedly executes a set of instructions as the iterator steps through a series of values. Types of iterative loops include for loops and foreach loops. An iterative loop is a repetition but with a variable dependent on the current iteration. This allows the looped procedure to vary slightly between iterations. For example, the same operation can be carried out on each iteration, but each time on a different object.
- Conditional loops
A conditional loop tests for a condition around the loop, and repeatedly executes a block of instructions whilst the condition is true. Types of conditional loops include while loops and do-while loops.
Examples here should be migrated to an appropriate Iteration page and removed from here. If a page does not exist demonstrating a particular loop structure, discuss it here.
68000 Assembly
NOT COVERED IN LOOP PAGES
The 68000 uses DBxx Dn, label
for loop counting. "Dn" refers to a chosen data register. The "xx" is replaced with the condition code of your choice (DBRA
stands for Decrement, Branch Always which is most commonly used). Execution will jump to the labeled line of code unless Dn's lower two bytes equal #$FFFF or the specified condition code is true, whichever occurs first. Keep in mind that the condition code has nothing to do with the value stored in Dn; rather, it represents the outcome of the operation just before the branch. This is similar to a "repeat until" construct in some other languages.
The below code snippet represents a loop that continues until a value greater than 3500 is read. However, it will also end after the 2000th iteration automatically, regardless of whether the condition is ever met.
MOVE.W #1999,D1 ;DBxx loop counters need to be pre-decremented to work properly, since they terminate at $FFFF rather than 0
LOOP:
MOVE.W (A0)+,D0
CMP.W #3501,D0 ;COMPARE TO #3501
DBCC D1,LOOP ;DECREMENT, BRANCH UNTIL CARRY CLEAR OR D1 = #$FFFF
AmbientTalk
doTimes
// print 1 2 3 ... 20
20.doTimes { |i| system.print(" "+i); }
each
Iterate over a collection:
[ "foo", "bar", "baz" ].each: { |e|
system.print(" "+e);
}
// prints: foo bar baz
AppleScript
NOT COVERED IN LOOP PAGES
repeat-until
set i to 5
repeat until i is less than 0
set i to i - 1
end repeat
repeat
--endless loop
end repeat
repeat-with
repeat with i from 1 to 20
--do something
end repeat
set array to {1,2,3,4,5}
repeat with i in array
display dialog i
end repeat
AssemblyScript
NOT COVERING ALL POSSIBLE LOOP OPTIONS
while
let done = false
while (!done) {
done = true
}
do while
let done = false
do {
done = true
} while (!done)
for
for (let i = 0; i < 10000; i++) {
i += i
}
Brainf***
NOT EXPLAINED THIS MUCH IN LOOP PAGES BF's only control flow construct of any kind is a loop. Two of the eight commands define the start and end of a conditional loop.
- [ - branch forward past matching ']' if the current cell is zero
- ] - branch back to the matching '[' if the current cell is non-zero
In practice this is equivalent to a "while not zero" loop in other languages.
[-] set current cell to zero
[->+>+<<]>>[-<<+>>] copy cell 0 to cell 1, using cell 2 as temporary storage
C++
Compile-Time Control Structures
Necessary? A compile-time for loop can be generated with template metaprogramming. Example:
// the loop
template<int start, int finish, template<int n, typename T> class X> struct loop
{
typedef typename X<start, typename loop<start+1, finish, X>::type>::type type;
};
// the termination of the loop
template<int finish, template<int n, typename T> class X> struct loop<finish, finish, X>
{
typedef typename X<finish, void>::type type;
};
// example usage: This implements just a very complicated way of building a multi-dimensional array
// the loop body
template<int n, typename T> struct build_array
{
typedef T type[n];
};
template<int n> struct build_array<n, void>
{
typedef double type;
};
// the loop execution: This is equivalent to
// typedef double array_type[2][3][4][5];
typedef loop<2,6,build_array>::type array_type;
Clojure
NOT COVERED IN LOOP PAGES
loop
;; loop/recur is the most general looping construct
(loop [lst [1 3 5 7]
ret []]
(if lst
(recur (rest lst) (conj ret (* (first lst) (first lst))))
ret))
==> [1 9 25 49]
Crack
For
for( i=0; i<9; i++)
cout ` $i\n`;
Curto
HACER-BUCLE
\ limite inicio HACER sentencias iteradas BUCLE
\ limite inicio HACER sentencias iteradas incremento +BUCLE
\ SALIR \ abandona bucle HACER
\ DBUCLE SALIR \ limpia contadores de la pila de retorno antes de abandonar la palabra actual
ejemplo: Dos iteraciones típicas
10 0 hacer i . bucle \ Imprime números de 0 a 9
10 0 hacer i . 2 +bucle \ Imprime números pares de 0 a 8
EMPEZAR-HASTA
\ EMPEZAR sentencias iteradas condicional HASTA
ejemplo: Cuenta hacia abajo desde un número dado a cero
: cuenta-abajo ( n -- ) empezar dup rc . 1- dup 0< hasta soltar ;
EMPEZAR-DENUEVO
\ EMPEZAR sentencias iteradas DENUEVO
ejemplo: repetir entrada de usuario (solo funciona en cli, no en la interface gráfica)
: porsiempre ( -- ) empezar tecla emitir denuevo ;
EMPEZAR-MIENTRAS-REPETIR
\ EMPEZAR sentencias iteradas incondicionales condicional MIENTRAS sentencias iteradas condicionales repetir
ejemplo: cuenta hacia abajo desde un número dado a uno
: cuenta-abajo ( n -- ) empezar dup mientras rc dup . 1- repetir soltar ;
Dafny
var i: int := 0;
while i < n
invariant 0 <= i <= n
decreases n - i
{
i := i + 1;
}
assert i == n;
Dao
For
for( i=0; i<9; ++i) io.writeln( i );
for( i = 0 : 8 ) io.writeln( i );
For In
items = { 1, 2, 3 }
for( item in items ) io.writeln( item )
While
i = 0
while( i < 5 ) { i += 1 }
Do While
i = 0
do { i += 1 } while( i < 9 )
Déjà Vu
For
Déjà Vu has a for-loop protocol, so you can write your own iterators. The most commonly used iterators are in
and range
. The first iterates over a list, the second takes two arguments and goes from the first to the second, like a classic for-loop.
for i range 1 3:
!print i # prints 1, 2 and 3
While
while true:
!print "This is the song that never ends..."
Repeat
repeat 3:
!print "This sentence is printed three times."
Factor
NOT COVERED IN LOOP PAGES
Looping
Most looping is done with recursion. Tail recursion is properly optimized.
: forever ( quot -- ) dup slip forever ; inline
[ "A hungry raptor stalks you..." print flush 2000 random sleep ] forever
Iteration
Most indices are implicit or not present at all.
3 [ "pint" drink ] times
{ "high" "level" "language" } [ print ] each
high
level
language
10 [ sq ] map
{ 0 1 4 9 16 25 36 49 64 81 }
{ 1 2 3 } { 4 5 6 } [ * ] 2map .
{ 4 10 18 }
10 [ even? ] subset .
V{ 0 2 4 6 8 }
0 10 3 <range> >array .
{ 0 3 6 9 }
10 1 -2 <range> >array .
{ 10 8 6 4 2 }
2222 [ dup 0 > ] [ 2/ dup ] [ ] unfold nip .
{ 1111 555 277 138 69 34 17 8 4 2 1 0 }a
Iterating with an index:
: indexed-alphabet. ( -- )
"abcdefghijklmnopqrstuvwxyz"
[ [ 1string ] [ number>string ] bi* ": " glue print ] each-index ;
Forth
DO-LOOP
( limit start ) DO ( iterated statements ) LOOP
( limit start ) DO ( iterated statements ) ( increment ) +LOOP
LEAVE \ exits a DO loop
UNLOOP EXIT \ cleans up loop counters from return stack before returning from the current word
example: Two standard iterations
10 0 DO I . LOOP \ Prints the numbers from 0 to 9
10 0 DO I . 2 +LOOP \ Prints the even numbers from 0 to 8
BEGIN-UNTIL
BEGIN ( iterated statements ) ( conditional ) UNTIL
example: Counts down from a given number to zero
: COUNTDOWN ( n -- ) BEGIN DUP CR . 1- DUP 0< UNTIL DROP ;
BEGIN-AGAIN
BEGIN ( iterated statements ) AGAIN
example: echo user's input
: FOREVER ( -- ) BEGIN KEY EMIT AGAIN ;
BEGIN-WHILE-REPEAT
BEGIN ( unconditional iterated statements ) ( conditional ) WHILE ( conditional iterated statements ) REPEAT
example: counts down from a given number to one
: COUNTDOWN ( n -- ) BEGIN DUP WHILE CR DUP . 1- REPEAT DROP ;
Additional WHILE clauses may be added to a loop, but each extra WHILE requires a matching THEN after the REPEAT.
Mixed Structures
Because Forth's compiler is laid bare to the programmer, it is quite easy to both define your own looping structures or combine existing structures in interesting ways. The rules for such combining are somewhat involved, though discussions can be found in the gforth user's manual, among other places. These more complex looping constructs can make up for Forth's lack of a "break" word, and can allow expressing complex loops without resorting to boolean variables. A practical example is also found in the Binary search task.
A good example of a useful combination is this complex loop:
BEGIN
( condition 1 )
WHILE
( condition 2 )
UNTIL
( condition 2 succeeded )
ELSE
( condition 1 failed )
THEN
An example of using this idiom in practice might be this pseudo-Forth
BEGIN
read-next-record
WHILE
found-record
UNTIL
process-record
ELSE
error" Ran out of records looking for the right one!"
THEN
FreeBASIC
While..Wend
Executes a block of statements while a condition is met.
While [ condition ]
[ statement block ]
Wend
For..Next
Executes a block of statements while an iterator is less than or greater than an expression.
For iterator [ As datatype ] = startvalue To endvalue [ Step stepvalue ]
[ statement block ]
Next [ iterator ]
Do..Loop
Executes a block of statements while or until a condition is met.
Do [ { Until | While } condition ]
[ statement block ]
Loop
or
Do
[ statement block ]
Loop [ { Until | While } condition ]
Intra-loop control
Continue While, Continue For and Continue Do
Prematurely re-enters a loop.
Continue {Do | For | While}
Exit While, Exit For and Exit Do Prematurely breaks out of a loop.
Exit {Do | For | While | Select }
Exit {Sub | Function | Operator | Constructor | Destructor | Property }
Exit {Do [, Do [ , ...] ] |
For [, For [ , ...] ] |
While [, While, [...] ] |
Select [, Select [ , ...] ] }
Frink
In all of the loops below, the curly braces can be omitted if the body is a single statement.
For Loop
A for
loop is really a foreach
loop that can work with range operators or iterate through various data structures. The to
operator creates an enumerating expression that lazily steps through its range.
for i = 1 to 1000000
{
println[i]
}
The to
operator can be combined with a step
statement:
for i = 1 to 1000000 step 3
println[i]
As a foreach
statement. The for
construct can iterate over the elements of an array, set, dictionary, or enumerating expression.
for i = [2,3,7,9]
println[i]
Do...While Loop
i=0
do
{
i = i+1
} while i<1000
Groovy
While Loops
while (true) { println 'groovy' }
For Loops
// iterate over a range x = 0 for (i in 1..3) { x += i } assert x == 6 // iterate over a list x = 0 for (i in [1, 2, 3]) { x += i } assert x == 6 // iterate over an array x = 0 for (i in (1..3).toArray()) { x += i } assert x == 6 // iterate over a map's key/value pairs x = 0 for (i in map) { x += i.value } assert x = 6 // iterate over a map's values x = 0 for (i in map.values()) { x += i } assert x == 6 // iterate over the characters in a string text = 'abc' list = [] for (c in text) { list.add(c) } assert list == ['a', 'b', 'c']
Each
def stringList = [ "java", "perl", "python", "ruby" ]; def stringMap = [ "Su" : "Sunday", "Mo" : "Monday", "Tu" : "Tuesday", "We" : "Wednesday", "Th" : "Thursday", "Fr" : "Friday", "Sa" : "Saturday" ]; stringList.each() { print " ${it}" }; println ""; // java perl python ruby stringMap.each() { key, value -> println "${key} == ${value}" }; // Su == Sunday // We == Wednesday // Mo == Monday // Sa == Saturday // Th == Thursday // Tu == Tuesday // Fr == Friday stringList.eachWithIndex() { obj, i -> println " ${i}: ${obj}" }; // 0: java // 1: perl // 2: python // 3: ruby stringMap.eachWithIndex() { obj, i -> println " ${i}: ${obj}" }; // 0: Su=Sunday // 1: We=Wednesday // 2: Mo=Monday // 3: Sa=Saturday // 4: Th=Thursday // 5: Tu=Tuesday // 6: Fr=Friday
Haskell
Most of the usual applications for loops are realized in Haskell by operations on (lazy) lists, like map, fold or filter. It's unusual to use loops in an imperative style. However, if one insists on it, it's easy to make your own implementation of any loop variant.
Here are a few examples:
Pre-checked loop (while)
whileM :: Monad m => m Bool -> m a -> m () whileM cond body = cond >>= \b -> if b then body >> untilM cond body else return ()
Post-checked loop (repeat-until)
untilM :: Monad m => m Bool -> m a -> m () untilM cond body = body >> cond >>= \b -> if b then return () else untilM cond body
For-style loop
Simplest done by iterating over a list:
forM :: Monad m => [a] -> (a -> m ()) -> m () forM [] f = return () forM (x:xs) f = f x >> forM xs f
IDL
It should be noted that IDL programmers tend to avoid loops -- most of the time loops are used to access the elements of arrays or vectors, and since IDL is an array language the same purpose can almost always be served in a faster, more elegant and more readable way though any of the array operations.
for
for i=0,50,2 do print,i
prints out every second number starting at 0 stopping at 50. Wherever a single command can go in IDL, there can always go a begin...end pair with arbitrary amount of code in between. Thus the above can also read
for variable = start, stop [,increment] do begin ;some code here ;some more code endfor
It is allowed but not required to use the appropriate "type of end" - i.e. it would be allowed to just say "end" instead of "endfor". However "endfor" (and "endwhile", "endif" etc) will throw an error if the wrong one is encountered at compile time and thus it is recommended to always use the more descriptive form since it makes debugging a lot easier.
while
while condition do command
Same extensions as above:
while running do begin ; various snippets of code that might change the variable ; "running" from something true to something false end[while]
repeat
repeat command until condition
etc
goto
'Goto' exists and can in principle be forced to make a loop:
label: ;some code [if condition then $] goto label
break
The break statement will immediately terminate the current innermost for, while, repeat, if, case or switch without having to resort to a goto.
Jinja
for
<lang jinja> print(Template("""{% for lang in ["Jinja", "Python", "Swift", "Nim"] %}
Template:Loop.index) Template:Lang {%- endfor %}""").render())
</lang>
Kabap
There is no native loop command in Kabap, but labels, variables, jumps and conditional execution are supported which is enough to create a basic loop structure. Support for native loops is being prepared for the next major release.
Basic loop
<lang Kabap>
$i = 0; :start; // Your loop code here $i = $i + 1; if $i < 20; goto start;
</lang>
Logo
forever [right random 360 forward 10]
repeat 5 [right 180-36 forward 100]
Repeat and forever also have access to a loop counter, starting at 1.
repeat 10 [print repcount]
while [:x > 0] [make "x :x / 2] do.while [make "x :x / 2] [:x > 0]
until [:x = 0] [make "x :x / 2] do.until [make "x :x / 2] [:x = 0]
LSE64
LSE's loop words all work via tail recursion, like Scheme, by re-executing the current word. If used interactively, "repeat" works upon the current line. Exiting words, like "&&", "||", and "exit" can be used to exit an otherwise infinite loop (see other tasks).
infinite : " again and " ,t repeat limited : continue? &repeat
Counted loops execute a specified word n times. Within that word, "count" accesses a loop counter, counted down to zero.
body : count , sp 10 body iterate # 10 9 8 7 6 5 4 3 2 1 body? : count , sp count 5 > 10 body? &iterate # 10 9 8 7 6 5
Make
Make does looping through recursion. SUCC=`expr $* + 1` MAX=10 all: 0-n; %-n: %-echo @-make -f loop.mk $(SUCC)-n MAX=$(MAX) %-echo: @echo $* $(MAX)-n: $(MAX)-echo;
Invoking it
|make -f loop.mk MAX=2 0 1 2
newLISP
dotimes
(dotimes (x 10) (println (+ x 1)))
do-until
(set 'x 1) (do-until (= x 10) (inc 'x) (println x))
do-while
(set 'x 1) (do-while (< x 10) (inc 'x) (println x))
for
(for (x 1 10) (println x))
OCaml
let rec
The for and while loops are imperative features of OCaml, and most often it is rather recommended to prefer using functional loop designed with recursive functions, or better when iterating over a list or an array using a built-in iterator from the standard library or the extLib library. <lang ocaml>let rec loop i =
Printf.printf "%d\n" i; if i <= 4 then loop (i + 1)
in loop 0</lang>
Built-in Iterators
<lang ocaml>List.iter List.fold_left Array.iter Array.iteri</lang>
Prolog
There are three primitive methods of looping in Prolog: recursion, fail-driven loops, and repeat-driven loops.
<lang Prolog>% recursion as loop print_each_element([]). print_each_element([E|T]) :- writeln(E), print_each_element(T).
% fail-driven loop fact(foo). fact(bar). fact(baz). print_each_fact :-
( fact(X), writeln(X), fail ; true ).
% equivalently %print_each_fact :- fact(X), writeln(X), fail. %print_each_fact.
% repeat-driven loop print_each_fact_again :-
repeat, fact(X), writeln(X), X = baz, !.
go :-
print_each_element([foo, bar, baz]), print_each_fact, print_each_fact_again.</lang>
Of the three recursion is the favoured approach as it requires no non-logical predicates and is thus easy to read in its declarative form.
The fail-driven loop form is a(n ab)use of the built-in backtracking mechanism of Prolog's reasoning engine. In the specific example provided, fact(X) will first succeed, binding "foo" to X. It will then write "foo" to the output (as a side effect of the writeln/1 predicate). It then hits the call to fail/0 which is a non-logical predicate which always fails and thus always triggers backtracking. On backtracking, the runtime will try fact(X) again and will find that it is true when X is bound to "bar". This will then print and backtrack again. A third time binds to and prints "baz". A fourth time will fail because there is no more solution to the goal "fact(X)". This triggers a further backtrack and a try on the second branch of the disjunction. That second branch invokes the true/0 predicate which always succeeds. This exits the query with an overall success.
The repeat-driven loop uses similar (ab)use of the backtracking mechanism. Instead of employing a predicate that always fails, however, it employs one that will always succeed: repeat/0. Thus, in this sample, fact(X) works as before, as does writeln(X), but the attempt to unify X with "baz" will fail for the first two attempts, causing the system to backtrack until it hits repeat. Since repeat always succeeds it drives the engine forward again, testing each fact in succession. Once X is unified with "baz" (which is to say once X contains the value "baz") the predicate carries on. The cut operator !/0, guarantees that the predicate won't be re-entered later.
As with any language permitting higher-order invocations, using the looping primitives directly as above is often not a desirable thing. Instead higher-order features would be used.
<lang Prolog>% using maplist/2 to replace explicit recursion on a list print_each_element(L) :- maplist(writeln, L).
% using forall/2 to replace an explicit fail-driven loop fact(foo). fact(bar). fact(baz). print_each_fact() :- forall(fact(X), writeln(X)).</lang>
There are a myriad of such predicates available in a useful Prolog implementation (SWI-Prolog provides, non-exhaustively: include/3, exclude/3, partition/4-5, maplist/2-5, foldl/4-7, scanl/4-6, aggregate/3-4, aggregate_all/3-4, forall/2, findall/3-4, findnsols/4-5, bagof/3, setof/3, … just as the more fundamental wrappings.) If the provided predicates do not permit the kinds of functionality desired for common patterns, it is trivial to make a new one. As an illustration, this is the source code for forall/2:
<lang Prolog>:- meta_predicate forall(0,0). forall(A, B) :- \+ (call(A), \+ call(B)).</lang>
Pop11
until
Variant of while is until loop:
until condition do /* Action */ enduntil;
is equivalent to:
while not(condition) do /* Action */ endwhile;
for
One can process all elements of a list:
for x in [a b c] do x => endfor;
It is possible to simultaneously process multiple lists:
for x y in [a b c], [1 2 3] do [^x ^y] => endfor;
in first iteration sets x to "a" and y to 1, in the second x is "b" and y is 2, in the third (last) iteration x is "c" and y is 3. The iteration ends when the shortest list is exhausted.
Sometimes one wants to process tails of the list, to do this use on keyword instead of in keyword:
for x on [a b c] do x => endfor;
in first iteration sets x to [a b c], in the second to [b c], etc...
There is also "counting" version of for loop:
for x from 2 by 2 to 7 do x => endfor;
goes trough 2, 4 and 6. Ommited by frase means by 1.
There is alse a C-like for loop:
for action1 step action2 till condition do /* Actions */ endfor;
is equivalent to
action1 while not(condition) do /* Actions */ action2 endwhile;
There are more specialized kinds of loops, but we skip them here.
quitloop quitif quitunless
Inside loops one can use control transfers to prematurely exit the loop or end current iteration and start the next one:
while true do n - 1 -> n; quitif(n=0); endwhile;
quits loop when n=0. quitloop unconditionally quits loop, quitunless(x) is equivalent to quitif(not(x)).
nextloop nextif nextunless
Similarely to quitloop nextloop unconditionally ends current iteration and starts the new one, nextif(x) ends current iteration when x is true, nextunless(x) is equivalent to nextif(not(x)). The loop control transfers can be also used inside for (and until) loops.
Finally, it is frequently possible to avoid explicit iteration using higher order map functions (like appdata and mapdata).
PostScript
The "for" operator expects three numbers and a procedure on the stack. It will consume all four arguments then it will push the first number on the stack, execute the procedure, increase the first number by the second number, push it on the stack, execute the procedure etc until the third number is reached. For example
10 12 200 {dup moveto 100 0 lineto} for stroke
will add lines to the currentpath that start at coordinates {10,10}; {22,22}; {34,34} ... and all end at {100,0}. The "stroke" operator then renders these lines on the current output device (usually a screen or a piece of paper).
Python
for
Frequently one wants to both iterate over a list and increment a counter:
<lang python>
mylist = ["foo", "bar", "baz"] for i, x in enumerate(mylist): print "Element no.", i, " is", x
</lang>
Iterating over more than one list + incrementing a counter:
<lang python>
for counter, [x, y, z] in enumerate(zip(lst1, lst2, lst3)): print counter, x, y, z
</lang>
list comprehension expressions
Typically used when you want to create a list and there is little logic involved. Faster than for loop:
positives = [n for n in numbers if n > 0]
A list comprehension is an expression rather than a statement. This allows them to be used as arguments to a function:
<lang python>
def square_each(n): results = [] for each in n: results.append(each * each) return results squares_3x5 = square_each([x for x in range(100) if (x%3)==0 and (x%5)==0]) # Return a list of all the squares of numbers from 1 up to 100 those numbers are # multiples of both 3 and 5.
</lang>
while
Typical use:
<lang python>
while True: # Do stuff... if condition: break
</lang>
You can add optional else, which is executed only if the expression tested was false. Typically used for searches.
<lang python>
while True: # Do stuff... if found: results = ... break else: print 'Not found'
</lang>
Since Python has no "bottom-tested" loop construct (such as "do ... until") ... it's common Python practice to either rethink the design in terms of iteration or to use an while 1 (infinite loop) and break out of it as appropriate.
Raven
each
10 each as i # counted loop "index is %(i)d\n" print 'hello world' each as c # string characters "%(c)c" print [ 'a' 'b' 'c' ] each as item # list items "%(item)s" print { 'a' 1 'b' 2 } each pair as k, v # hash key/val pairs "%(k)s => %(v)d\n" print 'SELECT * FROM table' mysql query each as row # iterable resource row print
repeat while/until
repeat <some_condition> while <some_process> repeat <come_condition> until <some_process>
REXX
repeat
This example shows how to perform a loop for one million times. <lang rexx>n= 1000000 x= 1 y= 12 z= 0
do n z=someFunction(z, x, y) end /*n*/</lang>
Seed7
In Seed7 new statements can be declared easily. This feature is not explained here. Here are examples of the predefined loops:
while
while TRUE do foo; end while;
repeat
repeat foo; until FALSE;
for
for i range 0 to 4 do foo; end for;
for i range 4 downto 0 do foo; end for;
for stri range []("foo", "bar", "baz") do writeln(stri); end for;
SETL4
<lang setl4>
define('prime(n)set.this') :(prime.end)
- Tests if _n_ is a prime integer.
prime
n = integer(n) +n eq(n,2) :s(return) even(n) :s(freturn) exists(new('iter 3 ' square.root(n) ' 2'), 'multiple(n,this)') :s(freturn)f(return)
prime.end
define('primes(n)set.this') :(primes.end)
- Returns set of primes less than _n_.
primes
primes = filter(new('iter 2 ' (n - 1)),'prime(this)') :(return) primes = new('set') iter = new('iter 2 ' (n - 1)) loop(iter)
primes.loop
this = next(iter) :f(return) prime(this) add(primes,this) :(primes.loop)
primes.end </lang>
SIMPOL
In SIMPOL there is only one looping construct. It is very flexible and can be used as a while, a repeat, or a combination of both.
while
<lang simpol>while [condition]
// Actions taken here
end while [condition]</lang>
Either condition or both can be present. Not setting either condition will result in an endless loop. The first condition will continue the loop if the result is true, the second will exit the loop if it is true. In SIMPOL code it is common to see both present, with the initial condition being the standard method of exiting the loop, and the end while condition used for exiting because of an error.
In this abbreviated example, the code will read records from a database table in a loop, placing each in record object in an array element, until it reaches the end of the table.
<lang simpol>function readrecs(sbme1table table)
sbme1record r array recs integer e, i
e = 0 i = 0 recs =@ array.new() r =@ table.select(error=e) while r !@= .nul i = i + 1 recs[i] =@ r r =@ r.select(error=e) end while e != 0
end function recs</lang>
The final condition should best be read as: "end the while, if this is true".
Another typical use of the loop is the traversing of rings that are commonly used in SIMPOL.
<lang simpol>function getfieldnames(sbme1table table)
sbme1field field integer i array fieldnames
fieldnames =@ array.new() i = 0 field =@ table.firstfield while field !@= .nul i = i + 1 fieldnames[i] = field.name field =@ field.next end while field =@= table.firstfield
end function fieldnames</lang>
Sing
<lang Sing>fn loops() void {
// while: the condition must be strictly of boolean type var idx = 0; while (idx < 10) { ++idx; }
// for in an integer range, the last value is excluded // it is local to the loop and must not be previously declared for (it in 0 : 10) { }
// reverse direction for (it in 10 : 0) { }
// configurable step. The loop stops when it >= the final value for (it in 0 : 100 step 3) { }
// with an auxiliary counter. The counter start always at 0 and increments by one at each iteration for (counter, it in 3450 : 100 step -22) { }
// value assumes in turn all the values from array var array [*]i32 = {0, 10, 100, 1000}; for (value in array) { }
// as before with auxiliary counter for (counter, value in array) { }
}</lang>
SNUSP
==in==!/==body==?\==out== \==ydob===/
The basic loop structure can be modified in many ways. You can have a pre-loop test by including ? before the loop.
A unique feature of SNUSP is the ability to write bi-directional loops, designed for different effect depending on which direction the flow of control is running around the loop. The two entry points into this subroutine will move a value either up or down one cell, determined by the direction the loop is circulating.
# # up1====?!/->+<\ ? ? down1==?!\<+>-/ # #
Sparkling
While loop (test-first loop):
<lang sparkling>var n = -1; print("Enter 0 to exit");
while n != 0 {
n = toint(getline()); print(n);
}</lang>
For loop (alternate form of test-first loop, idiomatic approach to counting):
<lang sparkling>var i; for i = 0; i < 10; i++ {
print(i);
}</lang>
Do-while loop (test-last loop):
<lang sparkling>print("enter empty line to exit");
var s; do {
s = getline(); print(s);
} while s != "";</lang>
Toka
countedLoop
Counts up or down until the boundaries are met.
10 0 [ i . ] countedLoop 0 10 [ i . ] countedLoop
whileTrue
Repeatedly executes a quote until the quote returns true.
100 [ dup . 1 - dup 0 <> ] whileTrue
whileFalse
Repeatedly executes a quote until the quote returns true.
0 [ dup . 1 + dup 101 = ] whileFalse
Tern
Tern has several distinct loop statements.
Infinite Loop
<lang tern>let v = 0; loop {
println(v++);
}</lang>
While Loop
<lang tern>let v = 0; while(v < 100) {
println(v++);
}</lang>
For Loop
<lang tern>for(let v = 0; v < 100; v++) {
println(v);
}</lang>
For In Loop
<lang tern>for(v in 0 to 99) {
println(v);
}</lang>
Woma
Woma is limited to for loops.
Infinte Loop
<lang woma>i<@>iter(int, 1)
print(i)
</lang>
For Loop
<lang woma>i<@>range(100)
print(i)
</lang>