Iterate
- Not to be confused with ITERATE.
Iterate is a Turing complete programming langugage invented by User:Aadenboy which only uses iterative loops.
Syntax
Loops
Loops are initialized with an asterisk (optionally with a number preceding it surrounded by parentheses), followed by the amount of times it loops, then the loop itself. There are only loops. Outside of a loop, its index is zero.
Code | Definition |
---|---|
*#< ... >
|
Loop # times. If it is zero or nothing, don't run. The visit count will still accumulate regardless of whether or not it had looped. |
*∞< ... >
|
Loop forever. |
*< ... >
|
Skip the code inside. |
(#*)...< ... >
|
A labeled loop for future reference. # must be a number. Different loops can share a single label if they are within separate scopes. |
(*)...< ... >
|
The main loop. This must enclose the entire program. |
A visit is defined as every time the program encounters a loop or label, regardless of whether or not the body actually runs. Note the difference between loops and labels, as labels can be shared across loops, so long as a label only appears once within its scope.
Loop amounts
You are able to provide different loop amounts via referencing other loops, or by a constant. A loop many only use one amount.
Code | Definition |
---|---|
Number | That many times. |
∞
|
Infinity. |
?
|
File: Advances the cursor to and uses the first string of numbers to the right of the cursor, or to EOF with 0 if there is none.
|
~?
|
File: Parses the next bytes as a UTF-8 character, returning the codepoint. If it is invalid, it is equivalent to zero and all invalid bytes are skipped.
|
%?
|
File: Returns the next byte.
|
n
|
The current index of the parent loop. This equals zero for the main loop's parent. |
n#
|
The current index of label #. This equals zero if the label doesn't exist. |
n^
|
The current index of the main loop. |
~n
|
How many loops are left until the parent loop's final loop. This equals zero for the main loop's parent. |
~n#
|
The above command, but with a label. This equals zero if the label doesn't exist. |
~n^
|
The above command, but with the main loop. |
=
|
How many times the parent loop was visited. This is not the same as how many times a label was visited. This equals zero for the main loop's parent. |
=#
|
How many times a label was visited. This is not the same as how many times a certain loop was visited. This equals zero if the label doesn't exist. |
=^
|
The above command, but with the main loop. Usually equal to one unless you explicitly reset it. |
For the input values (?
, ~?
, and %?
), behavior will vary for file/data stream input and CLI input.
Commands
These are placed in a loop.
Code | Definition |
---|---|
!
|
Immediately break out of the parent loop. Analogous to break .
|
!#
|
Immediately break out of label # IF you are inside it. This is a no-op if otherwise. |
!^
|
Stop execution. |
&
|
Skip to the end of the parent loop. Analogous to continue .
|
&#
|
Skip to the end of label # IF you are inside it. This is a no-op if otherwise. |
&^
|
Skip to the end of the main loop. |
@
|
Output the current index of the parent loop as a number. |
~@
|
Output the current index of the parent loop as a UTF-8 formatted character. |
%@
|
Output the current index in byte form, mod 256. |
$
|
Reset the visit count of the parent loop. |
$#
|
Reset the visit count of label #. |
$^
|
Reset the visit count of the main loop. |
Completeness
Iterate is Turing complete. See Iterate/Turing-completeness proof.
Unsolved question: Is Iterate Turing complete without the $#
command?
Basic arithmetic
For a complete list of mathematical operations, see Iterate/Math.
A+B
(*)1< *?< (1*)<> > // increment L1 *?< (1*)<> > // increment L1 again (2*)=1< // output character *~n< &2 > // skip to prevent early prints @ !^ // end early to avoid printing 0 case > (3*)48< // print 0 as its ASCII code (48) *~n< &3 > // skip to prevent early prints ~@ > >
A-B
Note: Results lower than one will not output anything.
(*)1< *?< (1*)<> > // L1 = A *?< // decrement L1 by one B times $2 *=1< // store L1-1 in L2 *~n< (2*)<> > // ~n acts as L1-1 ! > $1 *=2< (1*)<> > // copy from L2 to L1 > (3*)=1< // output character *~n< &3 > // skip to prevent early prints @ !^ // end early to avoid printing 0 case > (4*)48< // print 0 as its ASCII code (48) *~n< &4 > // skip to prevent early prints ~@ > >
A*B
(*)1< *?< (1*)<> > // store A to L1 *?< (2*)<> > // store B to L2 *=1< *=2< (3*)<> // visited A*B times as an intrinsic property of nested loops > > (4*)=3< // output character *~n< &4 > // skip to prevent early prints @ !^ // end early to avoid printing 0 case > (5*)48< // print 0 as its ASCII code (48) *~n< &5 > // skip to prevent early prints ~@ > >
A%B
(*)1< *?< (1*)<> > // L1 = A *?< (2*)<> (4*)<> > // L2 = B, L4 = B (6*)=1< // increment L3 to equal L1 (3*)<> // L3 = L3 + 1 $5 *=4< (5*)<> > // L5 = L4 $4 *=5< *~n< (4*)<> > // L4 = L5 - 1 ! > *=4< &6 > // if L4 == 0 (or when modulus returns 0)... $3 // L3 = 0 *=2< (4*)<> > // L4 = L2 (reset count) > (7*)=3< // print result *~n< &7 > // skip to prevent early prints @ !^ // end early to avoid printing 0 case > (8*)48< // print 0 as its ASCII code (48) *~n< &8 > // skip to prevent early prints ~@ > >
A/B
The same algorithm can be used to calculate floored division.
(*)1< *?< (1*)<> > *?< (2*)<> (4*)<> > (6*)=1< // a%b algorithm (3*)<> $5 *=4< (5*)<> > $4 *=5< *~n< (4*)<> > ! > *=4< &6 > $3 *=2< (4*)<> > (7*)<> // count how many times L3 resets for the quotient > (10*)1< (8*)=7< // print quotient *~n< &8 > @ !10 > (9*)48< *~n< &9 > ~@ > > (11*)82< // "R" *~n< &11 > ~@ > (12*)=3< // print remainder *~n< &12 > @ !^ > (13*)48< *~n< &13 > ~@ > >
Conditionals
While this code checks if A == B, you can trivially modify it to check for A < B, A > B, and any combination or negation of those cases.
(*)1< *?< (1*)<> > // L1 = A *?< (2*)<> > // L2 = B // L7 will hold if A == B: 1 = true, 0 = false // we'll continuously decrement A and B until either reaches 0 // if either reaches 0 first before the other, they're not equal // otherwise they are equal (5*)∞< (6*)1< // we check FIRST for the edge case where either A or B starts as 0 *=1< *=2< !6 > // case 1: neither A nor B are 0 -> continue !5 // case 2: B reached 0 first -> A > B > *=2< *=1< !6 > // case 1: neither A nor B are 0 -> continue !5 // case 3: A reached 0 first -> A < B > (7*)<> // case 4: both reached 0 at the same time -> A == B !5 > $3 $4 *=1< (3*)<> > // L3 = L1 *=2< (4*)<> > // L4 = L2 $1 $2 *=3< *~n< (1*)<> > ! > // L1 = L3 - 1 *=4< *~n< (2*)<> > ! > // L2 = L4 - 1 > *=7< @ !^ > // print 1 if true (8*)48< // print 0 if false *~n< &8 > ~@ > >
Arbitrary memory
Arbitrary memory can be implemented with a single label using arbitrary memory emulation.
Example programs
Hello, world!
(*)1< *1< (1*)72< *~n< &1 > ~@ ! > > // H *1< (1*)101< *~n< &1 > ~@ ! > > // e *1< (1*)108< *~n< &1 > ~@ ~@ // ll *1< (2*)111< *~n< &2 > ~@ // o *1< (3*)44< *~n< &3 > ~@ ! > > // , *1< (3*)32< *~n< &3 > ~@ ! > > // *1< (3*)119< *~n< &3 > ~@ ! > > // w ~@ ! > > // o *1< (2*)114< *~n< &2 > ~@ ! > > // r ~@ ! > > // l *1< (1*)100< *~n< &1 > ~@ ! > > // d *1< (1*)33< *~n< &1 > ~@ ! > > // ! >
Cat program
(*)∞< (2*)1< (1*)?< // get input *~n< &1 > // skip all actions until the index equals the character ~@ // output the character &2 // skip past the break > !^ // if input is 0, assume no more input and stop execution > >
Truth-machine
(*)1< *?< // if input were to be 0, this wouldn't run *∞< // loop forever *1< @ > // loop for index of 1 printed > > (1*)48< // printing 0 as its ASCII code (48) *~n< &1 > // skip to prevent early prints ~@ > >
Looping counter
(*)∞< *n< (1*)42< *~n< &1 > ~@ > > (1*)10< *~n< &1 > ~@ > >
Triangular numbers
(*)∞< *n< *~n< (1*)<> > ! > (4*)1< (2*)=1< *~n< &2 > @ !4 > (3*)48< *~n< &3 > ~@ > > (5*)10< *~n< &5 > ~@ > >
FizzBuzz
(*)∞< $1 $2 $3 $4 $5 $6 $7 $8 $9 $12 *n^< (1*)<> > *3< (4*)<> (5*)<> > // mod 3 *5< (6*)<> (7*)<> > // mod 5 *=1< // calculates mod 3 and mod 5 at the same time (2*)<> (3*)<> $8 $9 *=5< (8*)<> > *=7< (9*)<> > $5 $7 *=8< *~n< (5*)<> > ! > *=9< *~n< (7*)<> > ! > *1< (10*)1< *=5< &10 > $2 *=4< (5*)<> > > > *1< (10*)1< *=7< &10 > $3 *=6< (7*)<> > > > > *1< (11*)1< // if mod 3 == 0 *=2< !11 > *1< (12*)70< *~n< &12> ~@ > > // F *1< (12*)105< *~n< &12> ~@ > > // i *1< (12*)122< *~n< &12> ~@ ~@ > > // zz > > *1< (11*)1< // if mod 5 == 0 *=3< !11 > *1< (12*)66< *~n< &12> ~@ > > // B *1< (12*)117< *~n< &12> ~@ > > // u *1< (12*)122< *~n< &12> ~@ ~@ > > // zz > > (13*)n< // print number if neither condition was met *=12< !13 > *~n< &13 > @ > (14*)10< // newline *~n< &14 > ~@ > >