Callback Functions


Variable callbacks are functions associated with global variables, including dependencies, (or, indeed, functions or names that do not yet have a value) that are called just before or after Assignments or certain Selective Assignments are made to those variables. Variable callback functions are the subject of this chapter and will usually be spoken of as just "callback functions". Callbacks are particularly important for asynchronous events, such as in screen management in the s context, for tracking user actions; see "Interprocess Communication: adap", and "Introduction to Screen Management" and the chapters that follow it.

A mapped file mf can have an associated callback, but that callback is associated with the variable mf, not the underlying file. A change to the file through another mapped variable, in the same process or not, or by any other means than an assignment to mf will not trigger a callback for mf.

In A+, variable callback functions (as distinct from event callback functions) have the same basic syntax (variations are discussed below):

     cfn{s;d;i;p;c;v}
For example, if the function cfn is associated with the global variable price defined in the context comp, then when price changes, cfn is automatically called with arguments supplied by A+:
  1. s is static data (see below);

  2. d is the new value, i.e., the value of the righthand side of the Assignment triggering the callback;

  3. i is an index or set of indices (left argument to Choose - see p);

  4. p is a path (left argument to Pick) such that i#pprice is the subarray that changed;

  5. c is the name of the context, in the form of a symbol, `comp; and

  6. v is the name of the global variable in the form of a symbol,`price.
When cfn is called because of an Assignment of a global variable, the change to that variable can be described in terms of the arguments to cfn as

     (i#pc%v)d    if i is nested, or
     (i#,pc%v)d   if i is simple, or
     (pc%v)[,]d   if i is out of range for c%v before this assignment.

The last case involves the Append form of Selective Assignment and i is the set of indices in pc%v (after the assignment) of the appended elements.

The first argument of a callback function is called the static data. Static data is specified when the association between a variable and a callback function is established. Typically, the static data is any constant extra information needed to process the change in the associated variable.

A callback function can have anywhere from zero to six arguments, but no matter how many it has, their meaning from left to right is the same as above. For example, if f{a;b;c} is a callback function, then a is static data, b is new data, and c is an index.

The other type of callback is the event callback. Event callback functions have the basic syntax cfn{s;c;v} where the names s, c, and v have the same significance as above. An event callback function may have from zero to three arguments; the arguments are positional. See the chapters mentioned in the first paragraph of this chapter and especially "Attributes with Callbacks".

Setting and Causing Callbacks

A+ provides the Set Callback (_scb) and Set Preset Callback (_spcb) system functions for establishing and removing the association between a global variable and a callback function. Set Callback is discussed here, and Set Preset Callback below. The left argument is a symbol naming the global variable. The right argument is a pair of the form (fcn_name;static_data), where static_data is the static data (perhaps Null), and fcn_name is a function expression, a name entered without backquote or quotes. Thus the first element of this argument, with the enclosure by strand, is a function scalar and not a name, so this association is unaffected by any later changes to the meaning of the name of fcn_name. For example:
     cbf{s;d;i;p;c;v}:(s;d;i;p;c;v)    A callback function.
     `a _scb (cbf;'-- a --')    Call cbf whenever a is specified.


     a92        Specify a and see the arguments to the callback function.
< -- a --        Static data s
<  92            New data d
<                Index i is null.
<                Path p is null.
< `              c names the root context.
< `a             v names the variable a

     a10 20 30 40   Set a and see args to cbf
< -- a --
<  10 20 30 40
<
<
< `
< `a

     a[1]200        Indexed Assignment.
< -- a --
<  200
<  1
<
< `
< `a

     `a _scb (;)     Remove the callback on a and
     a999           see no callback.
     a
 999

     $cx ctx         Set new context.
     b(`scalar`vector`matrix; (3.14; 'abcdef'; 3 2))
     `b _scb (.cbf;'-- b --')   Call cbf when b changes.

     (1;0)#`matrixb        Pick-Choose 2 from the matrix.
 2

     ((1;0)#`matrixb)22   Change the 2 to a 22.
< -- b --
<  22
< < 1                       Index (1;0)
  < 0
<  `matrix                  Path `matrix
< `ctx
< `b

     (1;0)#`matrixb        Pick-Choose 22 from the matrix.
 22

   Selective Assignment Causes Callbacks

Any form of Selective Assignment can cause a callback function to be executed. Taking the last example from the previous section and continuing:
     (1 0/b)<`Scalar`Vector`Matrix
< -- b --
< < `Scalar `Vector `Matrix
< 0               Index is 0.
<                 Path is Null.
< `ctx
< `b
     b            And the change was made.
<  `Scalar `Vector `Matrix
< <  3.14
  <  abcdef
  <    0  1
      22  3
       4  5
The next example shows an Append Selective Assignment triggering a callback:

     x10
     `x _scb (.cbf;'-- x --')
     x[,]100 200
< -- x --         The callback was triggered.
<  100 200
< <  10 11
<
<  `ctx
<  `x

   Avoiding Callbacks

There may be times when you want to avoid callbacks - for example, when you are clearing a suspension and with normal execution many more suspensions would occur because of errors in callback functions. You can use the $Sf command for that purpose. See "Callback Flag" and note the warnings there.

When Callbacks Occur

It is important to know that callbacks established by _scb are called after the associated global variables have changed. This can be verified by defining a callback function that displays the value of the associated variable. When the function is called, the new value of the variable will be displayed, not the old. Note that the callback argument d is not necessarily this new value; d is, rather, the explicit result of the Assignment.

An ordinary callback function on a dependency is not called when the dependency definition is evaluated, although a preset callback function is. Similarly, during a callback on a dependency, the dependent variable's value is not marked invalid by any change the function makes in a variable on which the dependency depends.

   Preset Callbacks

It is also possible to establish callbacks that are called just before the value of a variable is changed, so that the change can be validated. To do so, use the system function _spcb, which takes the same arguments as _scb.

The differences between callback functions established by _spcb and _scb are:

Since preset callbacks are used for validating new values of global variables, the following rules should be followed in their definitions:

   Callbacks during Dependency Evaluations

The evaluation of a dependency can trigger a callback on the dependent variable, one that was established by the Set Preset Callback function - but not one that was established by the Set Callback function. The callback occurs after the definition body has been evaluated and before the dependent variable is set. The second argument to the callback is the result of evaluating the definition body, and the result of the callback is the value to which the dependent variable is set - or to which the items of the dependent variable are set, in the itemwise case.

Moreover, when a dependency is evaluated, callbacks of either kind can be triggered by assignments to other variables during the evaluation. These callbacks may mark saved values of other dependencies invalid.

A dependency that is currently being evaluated, however, or indeed a dependency whose callback function is being executed is marked as being in that state, and so its value will not be marked invalid while the evaluation or execution is going on.

Evaluation of a dependency is not complete until all callbacks, including any on the dependent variable, have been finished. See "Dependencies" for an example.

   Callbacks during Protected Execute and Monadic Do

An error that occurs during the execution of a callback within the execution of a Protected Execute or Monadic do is reported in the result of the protected execution.

doc@aplusdev.org© Copyright 1995–2008 Morgan Stanley Dean Witter & Co. All rights reserved.