A+ Reference: Control Statements

# Control Statements

Error Reports
Definitions of Control Statements

Case
Do - Monadic (Protected Execution)

Table: Error codes for Protected Execution

Do - Dyadic (Iterative Do)
If
If-Else
While

> Unlike functions and operators, which take arguments and return results, control statements are primarily used for their side effects, although they always do have explicit results. Some control statements also have syntax that differs from that of functions taking arguments. The keywords are reserved: the words or names case, do, if, else, and while can appear only as parts of control statements as shown in this chapter.

# Error Reports

> Multiple errors elicit but one report before suspension. Because these control statements are complex, the order in which the reports are listed here is not necessarily A+'s order of reporting in any particular situation. The five kinds of reports are:

> - parse;
> - value: an argument has no value;
> - wsfull: the workspace is currently not large enough for the execution of the statement; a bare left arrow (û), which dictates resumption of execution, causes the workspace to be enlarged if possible;
> - a report from an included function;
> - interrupt (not an error): the user pressed c twice (once if A+ was started from a shell) while holding the Control key down.

# Definitions of Control Statements

## Case

Syntax

> There are two forms of case statement:

>     case (target) {value0; expression0;
>                    value1; expression1;
>                       * * *
>                    valueN; expressionN;
>                    default}

>     and

>     case (target) {value0; expression0;
>                    value1; expression1;
>                       * * *
>                    valueN; expressionN}

> where case is a keyword, and target, value0, ... , valueN, expression0, ... , expressionN, and default are each an expression or expression group.

Definition

> The values of target, value0, ... , valueN are subject to the requirement that targetÅvalueN must be a valid expression for each value0, ... , valueN. The case statement is evaluated as follows: the test

>          1ÅtargetÅvalue0

> is made. If the result of the test is 1, then expression0 is evaluated and its result is the case statement result. No further evaluations within the case statement are made. Otherwise, the expression value1 is evaluated and if the result of the test

>          1ÅtargetÅvalue1

> is 1, then expression1 is evaluated and its result is the case statement result. This continues until all the expressions up to valueN have been evaluated and tested. If all tests fail and the expression default is present, then it is evaluated, and its result is the case statement result. If all tests fail and default is not present, the case statement result is the Null.

Additional Error Report:

> - An error report is issued by Find (É) if the results of target and some valuek are not a suitable pair of arguments for it.

Examples

>          matrix x : {
>               case (ÒÒx) {
>                    0 ; 1 1Òx;
>                    1 ; ((Òx),1)Òx;
>                    2 ; x;
>                    Ù`rank }
>               }
>          Òmatrix 4
>      1 1
>          matrix É3
>      0
>      1
>      2
>          matrix É2 3
>      0 1 2
>      3 4 5
>          matrix É3 4 5
>     .matrix: rank
>     *     ý

## Do - Monadic (Protected Execution)

Syntax

> do expression , where do is a keyword and expression is either an expression or an expression group.

Definition

> The do statement used monadically normally performs a protected execute of expression. That is, with one exception, execution of expression is always completed, or at least abandoned; it is never suspended. The exception: a suspension, with a stop error message, can be triggered by the Stop function (monadic ^) when `stop is 1, and by a few other operations, such as an attempt to give a bound variable an impermissible value. See the last example for treatment of input during a suspension within protected execution.

> Execution of monadic do is affected by the Protected Execute Flag, `Gf, as described below. `Gf is set by the command $Gf.

> The result of the do statement is usually a two-element vector of the form (error_code;result). If there is no error, the do result is always of that form, error_code is 0, and result is the result of expression.

> If an error was encountered when evaluating expression, there are three possibilities, depending upon the value of `Gf:

> - If `Gf is 1 (the normal case), then error_code is nonzero, and result is a character string holding the error message. The table "Error codes for Protected Execution" lists the error codes and messages.

> - If `Gf is 2, then the do result has three items, the first two as just described and a third containing the value of $si at the time of the error.

> - If `Gf is 0, then the execution is not protected and the error message and suspension occur just as they would for expression alone.

> Error codes for Protected Execution
> If Error Code is not zero, Error Name is the second element of the do result
> Error Code | Error Name | Example
> --- | --- | ---
> 0 | (no error) |
> -1 | segv, bus, or other error not detected directly by the interpreter, or a name from Signal | do Ù'error1' Signal function causes and names the error
> 1 | interrupt | do while(1)1 Interrupt: hold Control down, press c twice - once if A+ was started from a shell.
> 2 | wsfull | do 1e9Ò1
> 3 | stack | recurse x: recurse x do recurse 0
> 4 | value | do 1+abcd
> 5 | valence | do Å3
> 6 | type | do ß"a"
> 7 | rank | do 0#0
> 8 | length | do 1 2 + 3 4 5
> 9 | domain | do 0ß0
> 10 | index | do 9#É9
> 11 | mismatch | do 1 2 +@0 Û 3 4 5
> 12 | nonce | do 1 2ÙÉ3 5
> 13 | maxrank | do (10Ò1)Ò1
> 14 | nonfunction | do x@1 xû1
> 15 | parse | do â'+f' Where (f x:x), say.
> 16 | maxitems | do mp[,]ûitem Too many items.
> 17 | invalid | do {aû'abc'; `a .is `label; aûÉ3}
> 18 | nondata | do +{519;+}

> Monadic do's can be traced using $dbg do.

> Unlike Execute, do cannot successfully execute a command, a function definition, or, unless in braces, an expression that must be alone on a line. Thus 0â'$vers' and 0â'f{x}:{2«x+1}' and 0â'+@0' and 0â'ß' all give nonerror results (as does unprotected Execute); do $vers and do f{x}:{2«x+1} and do +@0 and do ß all yield error results; and do {+@0} and do {ß} both give nonerror results.

> Messages that are not strictly A+ error messages will still appear in the log, e.g.
> filename: No such file or directory
> not an `a object
> and many adap messages.

> Warning! Within a Monadic Do - as in a Protected Execute - Result (ûx) exits from Monadic Do only, with a 0 return code and the Result argument as result; it does not exit from the function containing the Monadic Do.

> Typically, the monadic do statement is used in the form:

>          if (0=0Øzûdo âx) {
>                 ... Normal processing for result 1Øz}
>          else { ... Error processing for error 1Øz}

> For an A+ process started from a shell, the Unix command kill -INT process-id can be used to interrupt protected execution, like Ctl-c Ctl-c from Emacs (or a single Ctl-c within a session started from a shell), and execution will continue with the next expression. If, however, this kill -INT signal is sent from the shell when protected execution is not in progress, it will cause A+ execution to halt.

Examples

>          y div x: {
>               case (0Øzûdo{yßx}) {
>                0; 1Øz;   ã Divide worked, return result.
>                9; 0;     ã Domain error, replace 0ß0 by 0.
>                ÙÂ1Øz }   ã Failed for another reason, so report.
>               }

>          2 3 4 div 5 2 1
>      0.4 1.5 4

>          2 2 ¢2 0 0 div 5 0 0 5 0
>      0.4 Inf ¢Inf 0 0    ã "Fixed" 0ß0, making it 0.

>          2 3 4 div 5 2
>      .div: length
>     *     ý

>          2 3 4 div 'abc'
>      .div: type
>     *     ý

>          a div aû5e6Ò2
>      .div: wsfull
>     *     ý

>     ã Treatment of input for immediate execution when stopped within protected execution.
>          no no no         ã An expression that cannot be parsed.
>     ã[parse] .no: var?
>          $stop 1
>          do {^aû,.0; (nû100)do a[,]û(¢200+5«n)ßn-40; a}
>     ã[error] : stop       ã Now stopped within immediate execution.
>     *     9 9 9
>      9 9 9                ã Result is displayed for any correct input.
>     *     nonono          ã Value error ignored: no suspension and NO display.
>     *     do nonono       ã The remedy is to use protected execution in input.
>     <  4                  ã Protected do is correct input; result is error it found.
>     < value
>     *     no no no        ã Parse error ignored: no suspension and NO display.
>     *     do no no no     ã Entire input cannot be parsed: do is ineffective.
>     *     do â'no no no'
>     <  15                 ã do result shows the parse error found by â in its arg.
>     < parse
>     *     ()â'no no no'   ã â result is code for parse error it found in its arg.
>      15
>     *     û               ã Continue from the point where stop occurred.
>     <  9                  ã Result reports domain error from 0ß0.
>     < domain

## Do - Dyadic (Iterative Do)

Syntax

> count do expression, where do is a keyword and count and expression are either expressions or expression groups. (Typically, count is an expression.)

Definition

> The value of count must be a restricted whole number (a scalar or one-element array). The expression named expression is evaluated count times. There are the same limitations on expression as were stated above in the definition of Monadic Do.

> If the expression count is a (perhaps parenthesized) variable name alone or a parenthesized expression that makes an assignment to a variable name, then within expression that variable is successively given the integer values 0, 1, ... , count-1 for the successive evaluations. In these cases, once execution of the do statement is complete, the value of that variable is an integer equal to the value of the expression count.

> If count is (*varname) or (*varnameû...) then execution proceeds as if the * were not present (including the value of varname after the do is completed) and for the successive evaluations of expression the variable is successively given the same integer values except that these values are given in decreasing order.

> The explicit result of the do statement is the result of the last evaluation of expression.

> Result (ûx) causes an exit from the function that contains the Protected Do.

Additional Error Report

> - A domain error report is issued if the result of count is not a restricted whole number.

Examples

>          zû0Ò0
>          nû10
>          n do zûz,n                 ã Variable name alone:
>      0 1 2 3 4 5 6 7 8 9            ã n is counted up from 0
>          n                          ã to its original setting
>      10

>          zû0Ò0
>          (iû10) do zûz,i            ã Assignment to a variable name:
>      0 1 2 3 4 5 6 7 8 9            ã similar treatment of i
>          i
>      10

>          zû0Ò0
>          vû`i
>          ((%v)û10) do zûz,%v        ã Not just a variable name:
>      10 10 10 10 10 10 10 10 10 10  ã %v remains 10 throughout

## If

Syntax

> if (condition) expression, where if is a keyword and condition and expression are either expressions or expression groups; typically, condition is an expression. If condition is either a single number or name, or it is an expression group and therefore in braces, the parentheses are not necessary (although perhaps still a good idea for clarity).

Definition

> The result of condition is a restricted whole number (a scalar or one-element array). If that result is nonzero then expression is evaluated, and the result of the if statement is the result of expression. Otherwise the result is the Null: i.e., the explicit result is Null if expression is not evaluated.

> A note on entry of this statement: A+ considers if (condition) entered alone on a line, with no pending punctuation, to be a complete statement, taking expression to be null.

Additional Error Report:

> - A domain error report is issued if the result of condition is not a restricted whole number.

Example

>          if (0=ÒÒx) xû,x

## If - Else

Syntax

> if (condition) expression1 else expression0, where if and else are keywords, and condition, expression1, and expression0 are either expressions or expression groups. Typically, condition is an expression. The parentheses are not necessary (although perhaps still a good idea for clarity) if condition is either a single number or name, or an expression group and therefore in braces.

Definition

> The result of condition is a restricted whole number (a scalar or one-element array). If that result is nonzero, then expression1 is evaluated. Otherwise, expression0 is evaluated. The result of the if-else statement is the result of whichever of expression1 or expression0 was evaluated.

Additional Error Report:

> - A domain error report is issued if the result of condition is not a restricted whole number.

Example

>          if (10¦|x) x else 10««x

## While

Syntax

> while (condition) expression, where while is a keyword and condition and expression are each either an expression or an expression group. Typically, condition is an expression. The parentheses are not necessary (although perhaps still a good idea for clarity) if condition is either a single name or an expression group and therefore in braces.

Definition

> The result of condition is a restricted whole number (a scalar or one-element array). If the value of condition is nonzero, then expression is evaluated. condition is evaluated again, and if its value is nonzero, expression is evaluated again. This continues until the value of condition is 0. The result of the while statement is the result of the last evaluation of expression. If expression is never evaluated, the result is the Null.

> A note on entry of this statement: A+ considers while (condition) entered alone on a line without pending punctuation to be a complete statement, taking expression to be null. If you inadvertently enter such a statement, you can recover by pressing Control and holding it while you press c twice.)

Additional Error Report:

> - A domain error report is issued if the result of condition is not a restricted whole number.

Example

>          penny x: {
>               mû0.01;
>               iû1;
>               while (m<x) {
>                    Õi,m;
>                    iûi+1;
>                    mûm«2 }; }
>          penny 1
>      1 0.01
>      2 0.02
>      3 0.04
>      4 0.08
>      5 0.16
>      6 0.32
>      7 0.64