unexpected things may happen if operations are performed on this list. It is important to understand that there is only one default value associated with a table. For example, if a program changes the contents of the default value, as int := table([ ])
no new elements are added towhile word := getword() do put(t[word],lineno)
t
; instead every reference to
t[word]
produces the default value, to which the value of linen
o
is added. There is never any assignment to t[word]
.the list concatenation operation creates a new list and assigns it towhile word := getword() do t[word] |||:= [lineno]
t[word
]
every time the do
clause is evaluated. The first time this
happens for a particular value of word, the empty list default value is
concatenated with a list containing the value of lineno
and
this new list is assigned. The default value itself is never modified.find(s1,s2)
can produce is max(*s2 - *s1 + 1,0)
.andreturn x
is simply an extra resumption in the second case if another result is needed in the context in which the corresponding procedure is called. This extra resumption is detectable in trace output, but otherwise does not affect program behavior. However, if the identifiersuspend x fail
x
is replaced
by an arbitrary expression, the two cases may produce very different results.
Even if this expression itself only produces a single result, it is resumed
in the second case, and this resumption may produce side effects. For example,
andreturn tab(i)
may behave very differently. In the first case, assumingsuspend tab(i) fail
tab(i)
itself succeeds, &pos
is left set to i. In the second case,
if the call is resumed, tab(i)
is resumed and it restores &pos
to its former value. The latter form generally is used in matching procedures
to assure that scanning state variables are restored to conform to the matching
protocol. In such cases, return tab(i)
would be an error. Another
way to think about it is that return
limits its argument to
at most one result. Thus,
andreturn expr
are equivalent (except for the extra resumption).suspend expr \ 1 fail
need not be failure. If awhile expr1 do expr2
break
expression in either expr1
or expr2
is evaluated, the outcome of the looping expression
is the outcome of the argument of the break
expression.break
expression. In
this case, the argument defaults to a null value. Consequently, if the break
expression in
is evaluated, the outcome of the looping expression is the null value. In fact, if this effect is not wanted,while expr1 do { . . . break . . . }
can be used to assure the outcome of the looping expression is failure.break &fail
break
expression can be a generator.
For example, if
is evaluated in a looping expression, the result sequence for the looping expression is {1, 2, 3, 4, 5}.break 1 to 5
produces the ucode fileicont -c inst.icn
inst.u1
. Getting at the ucode instruction
set this way is a good exercise it illuminates aspects of Icon that few
programmers ever think about.The program actually consists of a single 182-character line to avoid increasing its size with newline characters. We have broken it into separate lines here to fit it on the page.procedure y();initial|0.0[suspend(,)to"":create+- ?~=!@^*./\x/x*x%x^x<x<=x=x>=x>x~=x++x--x**x|| x<<x<<=x==x>>=x>>x~==x|||x+:=x<-x:=:x<- >x~===x&x.x?:=x\&pos["]]-case[]of{1:return};end