Next: , Previous: , Up: Statements   [Index]


7.6 ABSTAIN and REINSTATE

INTERCAL-72 C-INTERCAL CLC-INTERCAL J-INTERCAL
yes all versions all versions all versions

The statement identifier of a statement determines whether it’s in an abstained or reinstated state at the start of a program; these states determine whether the statement runs at all when it’s encountered. It is, however, possible to change this state dynamically during a program’s execution, and the statements to do this are rather appropriately named ABSTAIN and REINSTATE. There are two forms of each, one which takes a single line label (which must be constant in most compilers, but can instead be an expression in recent CLC-INTERCAL versions), and one which takes an intersection-delimited list of gerunds. They look like this:

DO ABSTAIN FROM ABSTAINING + REINSTATING
DO ABSTAIN FROM (10)
DO REINSTATE CALCULATING
DO REINSTATE (22)

(This also illustrates the gerunds used for these commands; note that ABSTAINING from REINSTATING is generally a bad idea!) The line referenced, or every command represented by any gerund referenced, are reinstated or abstained as appropriate (effectively changing the DO to DON’T (or PLEASE to PLEASE DON’T, etc.), or vice versa). Using these forms of ABSTAIN and/or REINSTATE won’t abstain from a command that’s already abstained, or reinstate a command that’s already reinstated.

There is a strange set of restrictions on ABSTAIN and REINSTATE that has existed since INTERCAL-72; historically such restrictions have not always been implemented, or have not been implemented properly. They together define an unusual interaction of ABSTAIN and GIVE UP (note, for instance, that there isn’t a gerund for GIVE UP). The wording used in the INTERCAL-72 manual is:

[...] the statement DO ABSTAIN FROM GIVING UP is not accepted, even though DON’T GIVE UP is. [...] DO REINSTATE GIVING UP is invalid, and attempting to REINSTATE a GIVE UP statement by line label will have no effect. Note that this insures that DON’T GIVE UP will always be a "do-nothing" statement.

This restriction was not implemented at all in the only CLC-INTERCAL version before 0.02 (i.e. version 0.01), or in C-INTERCAL versions before 1.26. The restriction was implemented in C-INTERCAL version 1.26 and CLC-INTERCAL versions 0.02 and later as “GIVE UP cannot be REINSTATED or ABSTAINED FROM”; however, this is not strictly the same as the definition used by INTERCAL-72 (C-INTERCAL still uses this definition in CLC-INTERCAL compatibility mode). The J-INTERCAL implementation of this restriction is to make REINSTATING or ABSTAINING from a line label that refers to a GIVE UP statement a compile-time error, but this does not fit the INTERCAL-72 definition either. The definition adopted with version 0.27 and later of C-INTERCAL, which is hopefully correct, is to allow abstaining from a GIVE UP statement by line number but to rule out the other three cases (reinstating by line number silently fails, reinstating or abstaining by gerund is impossible because there is no gerund).

As well as CLC-INTERCAL’s extension to abstain/reinstate by computed line number, there is also (since version 0.25) a C-INTERCAL-specific extension to ABSTAIN, also known as ‘computed abstain’, but with a different syntax and different semantics. It’s written like an ordinary ABSTAIN, but with an expression between the words ABSTAIN and FROM, for instance:

DO ABSTAIN #1 FROM (1000)
DO ABSTAIN .2 FROM WRITING IN

Unlike non-computed ABSTAIN, this form allows a command to be abstained from even if it’s already been abstained from; so if the first example command is run and line (1000) is already abstained, it becomes ‘double-abstained’. The number of times the statement is abstained from is equal to the number of times it was already abstained from, plus the expression (whereas with non-computed abstain, it ends up abstained once if it wasn’t abstained at all, and otherwise stays at the same abstention status). Reinstating a statement always de-abstains it exactly once; so double-abstaining from a statement, for instance, means it needs to be reinstated twice before it will actually execute.

There are many uses for ABSTAIN (both the computed and non-computed versions) and REINSTATE, especially when interacting with ONCE and AGAIN (see ONCE and AGAIN); the computed version, in particular, is a major part of a particular concise way to write conditionals and certain kinds of loops. They also play an important role in multithreaded programs.


Next: , Previous: , Up: Statements   [Index]