Flow-control structures: Difference between revisions

m
→‎{{header|Ada}}: added 'return'
(Added XPL0 example.)
m (→‎{{header|Ada}}: added 'return')
 
(8 intermediate revisions by 6 users not shown)
Line 1:
{{Task|Control Structures}}
{{Control Structures}}
[[Category:Flow control]]
 
;Task:
Line 136 ⟶ 137:
 
===exit===
Exit is used to break out of loops. Exit can be used with a label to break out of an inner loop to an outer loop and its enclosing outer loop:
<syntaxhighlight lang="ada">Outer:
loop
-- do something
loop
--if doFinished somethingthen
loop
-- do something else
exit Outer; -- exits both the inner and outer loops
end loopif;
-- do something else
end loop;</syntaxhighlight>
end loop;
end loop Outer;</syntaxhighlight>
or, more idiomatically,
<syntaxhighlight lang="ada">Outer:
loop
-- do something
loop
exit Outer when Finished;
-- do something else
end loop;
end loop Outer;</syntaxhighlight>
 
===return===
A procedure can be exited early, if there’s no more to be done.
<syntaxhighlight lang="ada">procedure Foo is
begin
-- do something
if Nothing_More_To_Do then
return;
end if;
-- do more
end Foo;</syntaxhighlight>
 
===asynchronous transfer of control===
A sequence of operation can be aborted with an asynchronous transfer of control to an alternative:
Line 786 ⟶ 810:
 
[[Category:E examples needing attention]] <!-- Needs runnable examples, description of escape-catch, and maybe links to other flow control pages -->
 
=={{header|EasyLang}}==
 
With '''break <n>''' you can break out of a nested loop
 
<syntaxhighlight>
sum = 80036
for i = 0 to 50
for j = 0 to 50
if i * i + j * j * j = sum
print i & "² + " & j & "³ = " & sum
break 2
.
.
.
</syntaxhighlight>
{{out}}
<pre>
23² + 43³ = 80036
</pre>
 
=={{header|Erlang}}==
Line 2,272 ⟶ 2,316:
1
 
=={{header|Quackery}}==
 
A Quackery program is a dynamic array ('''''nest''''') of numbers (bigints) operators (opcodes or primitives) and nests (named or explicit). It is evaluated by a depth first traversal of the structure, placing numbers on a data stack, and keeping track of the evaluation with a return stack. Flow control is achieved with meta-control flow operators, which modify the return stack during evaluation. The naming convention for meta-control flow operators is to wrap them in reversed brackets. They are <code>]again[ ]done[ ]if[ ]iff[ ]else[ ]'[ ]do[ ]this[</code> and <code>]bailby[</code>.
 
The first five, <code>]done[ ]again[ ]if[ ]iff[ ]else[</code>, are used to create a mix and match set of control flow words.
 
<pre>
[ ]again[ ] is again
[ ]done[ ] is done
[ ]if[ ] is if
[ ]iff[ ] is iff
[ ]else[ ] is else</pre>
 
<code>again</code> causes evaluation of the current nest to start again.
 
<code>done</code> causes evaluation of the current nest to end, and evaluation of the calling nest to continue.
 
<code>if</code> conditionally skips over the next item in the nest being evaluated. (dependant on the top of the data stack; it skips if the TOS is zero, and does not skip if it is a non-zero number. If it is not a number evaluation halts and a problem is reported.
 
<code>iff</code> is like <code>if</code> but conditionally skips over the next two items. It combines with <code>else</code> (below) to form an if...else... construct, and with other words to form more control flow structures (below).
 
<code>else</code> unconditionally skips over the next item in the nest being evaluated.
 
Also provided are <code>until</code> and <code>while</code>, and the programmer can add more as desired.
 
<pre>[ not if ]again[ ] is until
[ not if ]done[ ] is while</pre>
 
As this is a mix and match word set, complex control-flow structures can be made, restricted only to single-point of entry, achieved by the intentional omission of a <code>go-to</code> operator. For example, this code fragment from the task [[Largest number divisible by its digits#Quackery|Largest number divisible by its digits]].
<pre> [ 504 -
dup digits
dup 5 has iff
drop again
dup 0 has iff
drop again
repeats if again ]</pre>
 
<code>' do this</code>enable first and higher order functions, and recursion. They are defined using meta control flow operators.
<pre>
[ ]'[ ] is '
[ ]do[ ] is do
[ ]this[ ] is this</pre>
 
<code>'</code> unconditionally skips over the next item in the current nest, and places (a pointer to) it on the data stack.
 
<code>do</code> evaluates the item on the top of the data stack.
 
<code>this</code> places (a pointer to) the nest currently being evaluated on the data stack. so, for example, the phrase <code>this do</code> will cause the nest containing the phrase to be evaluated recursively. For convenience, the word <code>recurse</code> is provided which does the same thing.
 
<pre>[ ]this[ do ] is recurse</pre>
 
For more complex recursive situations the words <code>this</code> and <code>do</code> can be deployed at different levels of nesting, and additionally a forward referencing mechanism is provided. This example is from the task [[Mutual recursion#Quackery|Mutual recursion]].
<pre> forward is f ( n --> n )
 
[ dup 0 = if done
dup 1 - recurse f - ] is m ( n --> n )
[ dup 0 = iff 1+ done
dup 1 - recurse m - ]
resolves f ( n --> n )</pre>
 
<code>]'[</code> and <code>do</code> are also used to create the iterative looping word <code>times</code>, which will repeat the next item in the nest a specified number of times. The index of the loop is available from the word <code>i^</code>, which counts up from zero with each iteration, and the word <code>i</code>, which counts down to zero. The index can be modified with the words <code>step</code>, which causes the index to be incremented by a specified number, <code>refresh</code>, which resets it to the originally specified number of iterations, and <code>conclude</code>, which will sets it to zero.
 
<code>times</code> is used in the definition of <code>witheach</code>, which iterates over a nest placing the next item in the nest on the data stack with each iteration, so <code>I^ I step refresh conclude</code> are available within <code>witheach</code> loops.
<pre> ' [ 10 11 12 13 14 15 16 17 18 19 ]
witheach
[ dup 14 > iff
[ drop conclude ] done
echo
say " is item number " i^ echo cr
2 step ]</pre>
{{out}}
 
<pre>10 is item number 0
12 is item number 2
14 is item number 4</pre>
 
<code>witheach</code> can be used to define [[Higher-order functions#Quackery|Higher-order functions]].
 
<code>]bail-by[</code> removes a specified number of returns from the return stack. This is a high risk activity, as the data stack and ancillary stacks used by <code>times</code> and others are not restored in the process, additionally many words add items to the return stack that need to be accounted for. Without proper precautions it is an effective way of causing unpredictable behaviour (usually crashing). It exists primarily for the backtracking provided by the words <code>backup</code>, <code>bail</code>, and <code>bailed</code>, which do take the proper precautions.
 
=={{header|Racket}}==
Line 3,104 ⟶ 3,228:
 
The following code demonstrates each of the above apart from '''Fiber.suspend''' which simply exits a CLI script.
<syntaxhighlight lang="ecmascriptwren">var func = Fn.new { |n|
var i = 1
while (true) {
Line 3,120 ⟶ 3,244:
 
var fiber = Fiber.new {
Fiber.abort("Demo error") // error occcurredoccurred, abort script
}
 
Line 3,126 ⟶ 3,250:
for (n in a) {
func.call(n)
if (n > 2) return // end module and hence the script as itsit's a single module script
var error = fiber.try() // catch any error
System.print("Caught error: " + error)
5

edits