Icon+Unicon/Intro: Difference between revisions

(→‎Contractions: example in progress)
Line 628:
end</lang>
 
We can transform this. Even if this result isn't helpful, understanding what can be done and how it works may be useful for less extreme cases.
We can transform this.
 
Firstly, we can rewrite the while condition in the following ways:<lang Icon>while x ~= 0 & y ~= 0 do { # original
until not ( x ~= 0 & y ~= 0) do { # inverted
every | (0 = (x|y) & break) | &null do { # converted to an every loop (but incomplete)</lang>
One point worth noting is that expressions normally use short circuit evaluation. This construct forces both alternatives to be generated even if the second isn't needed. If ''y'' is a complex expression with side-effects this could have unexpected results.
 
The final transformation of a while into an ''every'' expression can be useful sometimes, but its not without challenges and can produce ugly results.
Line 645 ⟶ 646:
( x /:= 3 & y /:=3 ) # contracted</lang>
 
Putting these together and eliminating the trailing ''return'' in favor of the default fail at end, we get the rather odd looking:<lang Icon>procedure IsFilled("x,y)
every | ( (0 = (x|y) & return) | &null,
(( x % 3 = y %3 = 1) & break ) | &null,
( x /:= 3 & y /:=3 ) )
end</lang>
 
It's tempting to remove the ''| &null'' choices and convert the conjunction ''(expr1, expr2, expr3)'' to alternations but this isn't equivalent.
 
The alternations with &null can be eliminated by rewiring the path of alternatives with not expressions:<lang Icon>procedure IsFilled(x,y)
Line 663 ⟶ 666:
sequence each time, but failing if evaluation of expr results
in an empty result sequence.</pre>
 
The additional alternations are required to prevent the expression from running out of results. Part of this is due to the use of ''return'' and ''break'' to exit the loop preventing further results being generated.
 
Overall, this example is not a very good use of these techniques.
 
= Run Time Considerations =
Anonymous user