Next: Backtracking, Previous: Multithreading using COME FROM, Up: Multithreading and Backtracking [Index]
INTERCAL-72 | C-INTERCAL | CLC-INTERCAL | J-INTERCAL |
---|---|---|---|
no | version 0.27+ | version 0.05+ | no |
The WHILE
command (which is not strictly speaking a
command, but more a sort of metacommand that joins commands) is a
second method of achieving multithreading. (In
CLC-INTERCAL, there are at least two other meanings for
WHILE
, but only the one implemented in
C-INTERCAL is discussed here.) The syntax is somewhat
unusual, and consists of two commands separated by the
WHILE
keyword, but sharing the statement identifier,
execution chance, and any ONCE
/AGAIN
keyword
that may be present. For instance:
(1) DO COME FROM ".2~.2"~#1 WHILE :1 <- "'?.1$.2'~'"':1/.1$.2'~#0"$#65535'"$ "'"'&.1$.2'~'#0$#65535'"$#0'~#32767$#1"
(OK, maybe that’s an unnecessarily complicated example, and maybe
it shouldn’t have included the /
operator which is
part of another INTERCAL extension (see Operand Overloading). Still, I
thought that maybe you’d want to see how addition can be
implemented in INTERCAL.)
A WHILE
command starts two threads (the original thread
that ran that command and a new one), one of which runs the command to
the left of the WHILE
and one of which runs the command to
the right. Any line number applies to the left-hand command, not the
WHILE as a whole, which is a metalanguage construct. NEXTING
FROM
, ABSTAINING FROM
or similar behaviour with
respect to the WHILE
itself is impossible, although
it’s certainly possible to abstain from either of its operands
(and abstaining from the left operand has much the same effect as
abstaining from the WHILE
itself; the right-hand thread
deliberately takes a bit of time to get started just so that this
behaviour happens). The right-command thread starts just before the
left command is run (so NEXTING
, etc., directly to the
left command will not start that loop in the first place); if that
command finishes (which may be almost immediately for something like a
calculate command, or take a long time for something like
NEXT
), that thread loops and reruns that command as long
as the left command has not finished; COMING FROM
that
command, or a NEXT
/NEXT FROM
from/aiming at
that command, doesn’t count as finishing that command until it is
RESUME
d back to (if possible; if it’s come from,
that command can never end and the right-hand loop will continue
forever, or until it GIVE
s UP
or the loop
ends due to the command ending later in another thread). A
WHILE
command itself exists across all threads of a
multithreaded program in a way; for each left-hand command that ends
(in any thread), the next time a right-hand command of the same
WHILE
ends it will cause the thread it’s looping in
to end, regardless of whether that thread corresponds to the thread in
which the left-hand command ended. (As well as a right-hand command
ending, there’s also the possibility that it never got started;
there is a delay before the right-hand command runs during which a
left-hand command ending can prevent the right-hand thread starting in
the first place; this counts as the same sort of event as terminating a
right-hand loop, and can substitute for it anywhere a right-hand
command ending is mentioned.) There is one exception, in that if two or
more left-hand commands end in a space of time in which no right-hand
commands for that WHILE
ends, they together only cause one
right-hand command to end. (What, did you expect the logical and
orthogonal behaviour?)
The two threads produced by a WHILE
(the original thread
and a new copy of it) have more in common than ordinary
INTERCAL threads created by COME FROM
;
ordinary threads share only ABSTAIN
/REINSTATE
information, whereas the WHILE
-produced threads count as
‘woven’ threads which also share variables and stashes.
(They still have separate instruction pointers, separate instruction
pointer stacks, such as the NEXT stack, and separate choicepoint lists.
Overloading information is shared, though.) Being woven is a
relationship between two or more threads, rather than an attribute of a
thread, although a thread can be referred to as being unwoven if it is
not woven to any other thread.
Ordinary multithreading cannot create woven threads. When threads are
created by multiple COME FROM
s from an original thread,
which was woven with at least one other thread, one of the resulting
threads counts as the ‘original’ thread and remains woven;
the rest are ‘new’ threads which initially start out with
the same data as the original, but are not woven with anything.
Backtracking in a thread (see Backtracking) causes it to unweave with
any threads it may be woven with at the time (so the data in the thread
that backtracks is set back to the data it, and the threads it was
woven with at the time, had at the time of the MAYBE
, but
the other threads continue with the same data as before). The only way
to cause three or more threads to become woven is with a new
WHILE
inside one of the threads that is already woven,
which causes all the new threads to be woven together (the weaving
relationship is transitive).
Next: Backtracking, Previous: Multithreading using COME FROM, Up: Multithreading and Backtracking [Index]