SECTION 3

ACTIVE FUNCTIONS

An active function is a program that provides current information such as the date, name of the day, and name of your last message sender. Some of the information supplied by active functions can be supplied by commands, and in fact many active functions can act as commands, just as some commands can serve as active functions. But the principal service of an active function is to place current information in a command line that is then executed with that information as a part of the command's program. When active functions are typed in a command line, their programs are executed first and the results of those programs returned to the command line to be processed with the command. It is in this way that you can make many standard Multics commands conditional; that is, the results of the invocation of the complete command line depend upon the information received from the active function.

To see the results of an active function you can type some on a terminal as commands. Not all active functions can be typed as commands (those that can are listed in the MPM Commands), but the two that follow are used to demonstrate what results from the invocation of an active function. The first example shows an active function which returns information by itself, that is, without using a pathname:

tmpD5-1.gif

The second example uses an active function which requires a pathname argument for its operation:

tmpD5-2.gif

ACTIVE FUNCTIONS AS SUBSTRINGS

When an active function is used as an argument in a command line, the normal usage, it must be surrounded by brackets. The simplest form is:

[af arg1 ... argN]

where af is the name of an active function and argi represents the character string arguments to the active function. (Throughout Multics documentation, syntax lines that explain the structure of command lines containing a variable number of arguments use argument 1 (arg1) through argument N (argN), the N representing the number of the last argument used. Collectively, these arguments are referred to as argi.)

In the following example, an active function is included in a command line:

! send_message [last_message_sender] Thanks for the link.

When you type a newline and send this message to the command processor, the last_message_sender program is executed and the resulting value returned to the command line, in this case a User_id. The resulting value is not printed on the terminal, nor is the command line reprinted, but if it were it would look like this:

send_message JDoe.Pubs Thanks for the link.

That of course is just what would appear if you took the time to type the last message sender's User_id.

More than one active function can be used in a single command line. Suppose, for instance, that, wishing to keep track of the time you spend on individual jobs, you record the time at which you begin each job by sending yourself a message like the following:

! send_message [user name].[user project] Mailing list started at [date_time]

This command line uses the active function "user," which requires an argument (see the description of this active function in the MPM Commands). Here your Person_id and Project_id would be returned to the command line along with the date and time that you typed the message and it could all be saved in your mailbox as a message:

From Smith.Pubs 11/12/79 1200.7 est Mon:

Mailing list started at 11/12/79 1200.7 est Mon

Nesting Active Functions

Active functions can also be nested in a command line, that is, one function included within another. For instance, if you wish to underline the contents of a segment and have it printed on your terminal, you would use the string active function as a command and type:

! string [underline [contents seg_1]]

Of course, all executions within the brackets will be processed before the string command is processed. Each time the command processor encounters a right bracket (]) it returns to the matching left bracket ([) and evaluates the enclosed active function. This means that the innermost active function is evaluated first. To execute the above line, the command processor first evaluates [contents seg_1] and returns, for example:

On a clear day you can see forever.

Then the command processor evaluates the next element:

[underline On a clear day you can see forever.]

and returns:

On a clear day you can see forever.

The string command then operates on this string by printing it out on the terminal.

The term "active string" is often used interchangeably in Multics documentation with the term "active function." Actually, it refers to the entire string of characters enclosed within a single set of brackets, and this could include several separate active functions. Nesting, as we've just seen, is one way of including more than one active function within a set of brackets. Another way is to separate active functions with semicolons, as in the following:

! string [plus 3 4; times 5 6]

Here the active function string is used as a command on the active functions plus and times. The two active functions in this active string are processed separately and returned as arguments to the command. After the results of these two active functions have been returned, the command line is:

string 7 30

Since string used as a command simply prints the arguments that follow it, the printed result of this command line is:

7 30

Iteration of Active Functions

Active functions can also be used with iteration. (See Section 2 in this manual for a full description of iteration.) For example, if a segment named "all" contains the name of three segments, seg_1, seg_2, seg_3, then the command line:

! string [contents all]

will print the names returned by the active function contents:

seg_1 seg_2 seg_3

If, on the other hand, the active function was also included in parentheses:

! string ([contents all])

then the command would print the names of each of the three segments vertically:

seg_1
seg_2
seg_3

because the active function returns the three names within the parentheses so the command processed is:

string (seg_1 seg_2 seg_3)

In effect, the string command is being invoked three times in this command line, as if the line were:

string seg_1; string seg_2; string seg_3

Iteration can also be used within an active string, as in the following:

! string [(plus times) 2 3]

Here the two active functions are processed separately, each one using the arguments 2 and 3. Both active functions are processed before the command executes, so the command line becomes, in effect:

string [plus 2 3] [times 2 3]

This then becomes:

string 5 6

and the command execution causes the following line to be printed:

5 6

Rescanning

After an active string has been evaluated, the return value is rescanned for additional active strings before being inserted into the command line; the command processor continues scanning until all pairs of brackets have been evaluated. For example, if seg_4 contains just one line consisting of the string ([contents all]) described above, then the command line:

! string [contents seg_4]

invokes ([contents all]) as an active function which returns seg_1 seg_2 seg_3, the contents of the segment named "all," enclosed in parentheses so that the command is executed as:

string (seg_1 seg_2 seg_3)

or:

string seg_1; string seg_2; string seg_3

This rescanning can be stopped by placing a double vertical bar (||) before the active function. If, for instance, you want to print the contents of a segment which contains right and left brackets and not have those brackets interpreted as another active function, you would use the double vertical bar as it is used in the following command line:

! string ||[contents seg_5]

With this notation the entire returned value would go to the command processor without being checked again for brackets. Assume that the contents of seg_5 are:

Now [time of crisis] is the time for all good men to come to the aid of their country.

Without the double vertical bar, this returned value would be rescanned. The word "time" would be read as a valid active function, but since "of crisis" is not a valid argument for this function, an error message would be printed on the terminal. But with the double vertical bar in front of the original active function brackets, as in the above command, the string command will simply print out the above segment, including the brackets and enclosed phrase.

There also may be times when you wish to rescan a returned value for some reserved characters (see Section 2 in this manual for a list of reserved characters) but not for brackets. In those cases, a single vertical bar (|) will cause a returned value to be rescanned only for quotation marks. For example, consider the command line:

! string [contents seg_6]

where the contents of seg_6 are:

The symbol ] will be used to mark the end of each category.

After the first scanning of this command line, the returned value would be included in the line as:

string The symbol ] will be used to mark the end of each category.

Since the rescanning procedure continues until all brackets have been dealt with, this line would be rescanned and an error message returned because there is no left bracket to match the right one.

But if the command line included a single vertical bar before the active function:

! string |[contents seg_6]

then the returned sentence would not be rescanned for reserved characters such as brackets. The command would be sent to the command processor and the sentence, with the right bracket included, would then be printed.

ACTIVE FUNCTION ERRORS

If the command processor detects an invalid input argument or some other error in an active function that prevents it from returning the expected value, it signals the active_function_error condition. The standard system action for active_function_error is to print a message describing the error that was found and create a new command level. For example, in the following command line, arguments that designate segments have not been included with the contents active function, so an error message has been returned saying why the active function cannot be processed:

tmpD5-3.gif

You will note here that the command level is now level 2. Whenever another command level is created, the bad command line is held and you are shifted to a new command level. For this reason you should type:

! release

in order to release the bad command or commands and return to the original level. Then you can correct the error and retype the command line.

Not all errors made with active functions signal the active_function_error condition. For instance, if you do not match brackets properly, you will get an error message, but you will not be placed to another command level:

tmpD5-4.gif

Since the command processor has returned you to the original command level, you need not type release. You need only type the corrected command.

 

<< Previous Section                                          Next Section >>

Contents | 1 | 2 | 3 | 4 | 5 | 6 | 7 | A | B | C