Icon+Unicon/Intro: Difference between revisions

→‎Contractions: removed broken example
(→‎Contractions: - extreme title, more examples, replace due to logged out)
(→‎Contractions: removed broken example)
Line 616:
end</lang>
This is probably only lovable by J programmers.
 
 
Here is another example taken from [[Sierpinski_carpet|Sierpinski Carpet]] which we will explain in detail:
 
The procedure IsFilled is used to determine if the carpet is to be filled. The original version is a fairly straightforward translation of Java which in turn was translated from Python. About the only natural contraction for the language is the use of the fact that operators return values and comparisons can be chained.<lang Icon>procedure IsFilled(x,y)
while x ~= 0 & y ~= 0 do {
if x % 3 = y %3 = 1 then fail
x /:= 3
y /:=3
}
return
end</lang>
 
Taken to extremes we can write the following:<lang Icon>procedure IsFilled(x,y)
every | ((1 = x % 3 = y %3 & break)) | (x /:= 3 & y /:= 3) | return
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 =
Anonymous user