Modula-3: Procedure calls

## Procedure calls

A procedure call has the form:

        P(Bindings)

where `P` is a procedure-valued expression and `Bindings` is a list of keyword or positional bindings. A keyword binding has the form `name := actual`, where `actual` is an expression and `name` is an identifier. A positional binding has the form `actual`, where `actual` is an expression. When keyword and positional bindings are mixed in a call, the positional bindings must precede the keyword bindings. If the list of bindings is empty, the parentheses are still required.

The list of bindings is rewritten to fit the signature of `P`'s type as follows: First, each positional binding `actual` is converted and added to the list of keyword bindings by supplying the name of the `i`'th formal parameter, where `actual` is the `i`'th binding in `Bindings`. Second, for each parameter that has a default and is not bound after the first step, the binding `name := default` is added to the list of bindings, where `name` is the name of the parameter and `default` is its default value. The rewritten list of bindings must bind only formal parameters and must bind each formal parameter exactly once. For example, suppose that the type of `P` is

        PROCEDURE(ch: CHAR; n: INTEGER := 0)

Then the following calls are all equivalent:

        P('a', 0)
        P('a')
        P(ch := 'a')
        P(n := 0, ch := 'a')
        P('a', n := 0)

The call `P()` is illegal, since it doesn't bind `ch`. The call `P(n := 0, 'a')` is illegal, since it has a keyword parameter before a positional parameter.

For a `READONLY` or `VALUE` parameter, the actual can be any expression assignable to the type of the formal (except that the prohibition against assigning local procedures is relaxed). For a `VAR` parameter, the actual must be a writable designator whose type is the same as that of the formal, or, in case of a `VAR` array parameter, assignable to that of the formal.

A `VAR` formal is bound to the variable designated by the corresponding actual; that is, it is aliased. A `VALUE` formal is bound to a variable with an unused location and initialized to the value of the corresponding actual. A `READONLY` formal is treated as a `VAR` formal if the actual is a designator and the type of the actual is the same as the type of the formal (or an array type that is assignable to the type of the formal); otherwise it is treated as a `VALUE` formal.

Implementations are allowed to forbid `VAR` or `READONLY` parameters of packed types.

To execute the call, the procedure `P` and its arguments are evaluated, the formal parameters are bound, and the body of the procedure is executed. The order of evaluation of `P` and its actual arguments is undefined. It is a checked runtime error to call an undefined or `NIL` procedure.

It is a checked runtime error for a procedure to raise an exception not included in its raises set (If an implementation maps this runtime error into an exception, the exception is implicitly included in all `RAISES` clauses.) or for a function procedure to fail to return a result.

A procedure call is a statement only if the procedure is proper. To call a function procedure and discard its result, use `EVAL`.

A procedure call can also have the form:

        o.m(Bindings)

where `o` is an object and `m` names one of `o`'s methods. This is equivalent to:

        (o's m method) (o, Bindings)

    Last modified on Wed Apr  3 09:39:11 PST 1996 by heydon
         modified on Mon Apr 18 14:01:32 PDT 1994 by kalsow