Compute Fields

A computed field is a field that cannot be set by the web-client. Instead it is re-evaluated every time any of it's dependencies are updated.

An example:

Square:
    width: numeric
    height: numeric
    area:
        type: compute
        onchange:
            - width
            - height
        code: |
            fn compute_area() {
                not_null(self.width);
                not_null(self.height);
                return to_float(self.width) * to_float(self.height);
            }

Every compute field code block has access to a few global constants:

  • self - This constant allows convenient access to all the data fields on the Domain Entity this compute field is being evaluated for.
  • root - Like self, but provides full read-only access to the root level Domain Entity. This include instance ID-s and other metadata besides data fields.
  • by_id - Provides a map for looking up any Domain Entity by their ID.

The example above also makes use of a few APIs:

  • not_null - this is a special assertion function that stops the evaluation of the computed field safely without altering its value or causing an error
  • to_float - this ensures we use the same datatype for our calculation in case our numeric value was an integer

For more please see API Reference.

Note that a computed field can still be displayed as a form element like any other field.

Program structure

When compiling the compute field program the entry-point is picked by the following rules:

  • If a function with a name main is found then this is the entry-point
  • Otherwise the first non-anonymous function is designated as entry-point

For instance a more complex compute field could look like this:

    computed_field:
        type: compute
        onchange:
            - param1
            - param2
        code: |
            fn compute_param2() {
                not_null(self.param2);
                return to_float(self.param2) * 0.42;
            }

            fn main() {
                not_null(self.param1);

                let bias = some_module::do_complex_calculation(self.param1);
                not_null(bias);

                return bias + compute_param2();
            }

In versions <= 0.4.0 using expressions in the compute fields is not supported. The code block must define a function.