every-do
. Thus
in
once evaluation ofe1; e2
el
is complete, no failure in e2
can cause backtracking into e1
. Similarly, in
once evaluation of el is complete, failure inif e1 then e2 else e3
e2
or e3
cannot cause backtracking into e1
.ife1 || e2
e1
succeeds, but e2
fails, backtracking into
e1
occurs. If e1
produces an alternative, e2
is evaluated again.f(x | y)
f(x)
is called first. Should this call fail, backtracking to
the argument expression occurs, and f(y)
is called .e1
& e2
is simply an operation that returns its right operand (as
opposed to performing some computation).procedure compress(s,c) local x s ? { while tab(upto(c)) do x : = move(1) tab(many(x)) := "" } return &subject } end
tab()
is no longer
legal in Icon.c
may be a set of characters. (You might speculate
on the wisdom and possible consequences of returning from within a scanning
expression -- this style is used here to be compatible with both Versions
2 and 3.)x
cannot be removed as follows:
Consider the case in which there is just a single instance of a character ins ? { while tab(upto(c) do { tab(many(move(1))) := "" } return &subject }
c
. In the first solution
fails and no replacement is performed. This failure is of no consequence, sincetab(many(x)) := ""
has already movedx := move(1)
&pos
past this character. (There is an
implicit semicolon after the move
expression.) Note that the
compound expression in the do
clause fails, but this again
is of no consequence. (What would happen if backtracking was not limited
by while
and backtracking occurred into the control expression
tab(upto(c)
?) However, in
tab(many(move(1)))
many
results in backtracking into move. Although
move
has no alternatives, it does restore &pos
to its previous value. (What are the consequences of this?)Here the braces provide an explicit barrier to backtracking, preventings ? { while tab(upto(c)) do { tab(many({move(1})}) := "" } return &subject }
&pos
from being restored in case many fails.