Anonymous user
Icon+Unicon/Intro: Difference between revisions
→Extreme Contractions
(→Contractions: + extreme) |
|||
Line 617:
Here is another example taken from [[Sierpinski_carpet|Sierpinski Carpet]] which we will explain:
The procedure IsFilled is used to determine if the carpet is to be filled.
while x ~= 0 & y ~= 0 do {
if x % 3 = y %3 = 1 then fail
Line 626:
end</lang>
Taken to extremes we can write the following:<lang Icon>procedure
every | (
end</lang>
How did we get to this point:
* You can convert ''while'' loops into ''every'' loops with unary alternation (| expr)
* The first expression needs to cause procedure failure when x and y mod 3 are both 1. Using break exits the loop and fails by default at the end of the procedure.
* The second alternate expression divides x and y by 3 for the next iteration. This expression always succeeds and the loop continues. While there is nothing wrong with its position here, the construction is somewhat misleading.
* The last alternative succeeds ending the procedure. Often ending an every in "| return" is a bit of a cheap trick to save a line. However, here it works because we need the implicit failure at ''end''.
The above is a fairly elegant if somewhat extreme example of a contraction. A somewhat more intuitive version might be:<lang Icon>procedure IsFilled(x,y)
every | (1 = x % 3 = y %3, break) | return do
x /:= 3 & y /:= 3
end</lang>
And lastly a contrived and somewhat grotesque version:
<lang Icon>procedure IsFilled(x,y)
every (x *:= 3, y *:= 3, | (x /:= 3, y /:= 3,(x % 3 = y %3 = 1, break))) | return
end</lang>
... in which the conditional failure is moved to the bottom of the loop. The leading expressions are only evaluated once as the generated looping doesn't begin until the alternation operator. Now it's fairly common to need to initialize a variable at the beginning of a loop. This can be easily done with every, but it becomes a bit strained when performing multiple initializations.
= Run Time Considerations =
|